1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-02 20:35:25 +02:00

feat(tags): add the ability to manage tags (#1971)

* feat(tags): add the ability to manage tags

* feat(tags): update tag selector UX

* refactor(app): remove unused ui-select library
This commit is contained in:
Anthony Lapenna 2018-06-15 09:18:25 +02:00 committed by GitHub
parent b349f16090
commit 5e73a49473
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 942 additions and 118 deletions

View file

@ -27,6 +27,7 @@ type Store struct {
RegistryService *RegistryService
DockerHubService *DockerHubService
StackService *StackService
TagService *TagService
db *bolt.DB
checkForDataMigration bool
@ -45,6 +46,7 @@ const (
registryBucketName = "registries"
dockerhubBucketName = "dockerhub"
stackBucketName = "stacks"
tagBucketName = "tags"
)
// NewStore initializes a new Store and the associated services
@ -62,6 +64,7 @@ func NewStore(storePath string) (*Store, error) {
RegistryService: &RegistryService{},
DockerHubService: &DockerHubService{},
StackService: &StackService{},
TagService: &TagService{},
}
store.UserService.store = store
store.TeamService.store = store
@ -74,6 +77,7 @@ func NewStore(storePath string) (*Store, error) {
store.RegistryService.store = store
store.DockerHubService.store = store
store.StackService.store = store
store.TagService.store = store
_, err := os.Stat(storePath + "/" + databaseFileName)
if err != nil && os.IsNotExist(err) {
@ -99,7 +103,7 @@ func (store *Store) Open() error {
bucketsToCreate := []string{versionBucketName, userBucketName, teamBucketName, endpointBucketName,
endpointGroupBucketName, resourceControlBucketName, teamMembershipBucketName, settingsBucketName,
registryBucketName, dockerhubBucketName, stackBucketName}
registryBucketName, dockerhubBucketName, stackBucketName, tagBucketName}
return db.Update(func(tx *bolt.Tx) error {
@ -128,6 +132,7 @@ func (store *Store) Init() error {
Labels: []portainer.Pair{},
AuthorizedUsers: []portainer.UserID{},
AuthorizedTeams: []portainer.TeamID{},
Tags: []string{},
}
return store.EndpointGroupService.CreateEndpointGroup(unassignedGroup)

View file

@ -107,6 +107,16 @@ func UnmarshalDockerHub(data []byte, settings *portainer.DockerHub) error {
return json.Unmarshal(data, settings)
}
// MarshalTag encodes a Tag object to binary format.
func MarshalTag(tag *portainer.Tag) ([]byte, error) {
return json.Marshal(tag)
}
// UnmarshalTag decodes a Tag object from a binary data.
func UnmarshalTag(data []byte, tag *portainer.Tag) error {
return json.Unmarshal(data, tag)
}
// Itob returns an 8-byte big endian representation of v.
// This function is typically used for encoding integer IDs to byte slices
// so that they can be used as BoltDB keys.

View file

@ -0,0 +1,37 @@
package bolt
func (m *Migrator) updateEndpointsToVersion12() error {
legacyEndpoints, err := m.EndpointService.Endpoints()
if err != nil {
return err
}
for _, endpoint := range legacyEndpoints {
endpoint.Tags = []string{}
err = m.EndpointService.UpdateEndpoint(endpoint.ID, &endpoint)
if err != nil {
return err
}
}
return nil
}
func (m *Migrator) updateEndpointGroupsToVersion12() error {
legacyEndpointGroups, err := m.EndpointGroupService.EndpointGroups()
if err != nil {
return err
}
for _, group := range legacyEndpointGroups {
group.Tags = []string{}
err = m.EndpointGroupService.UpdateEndpointGroup(group.ID, &group)
if err != nil {
return err
}
}
return nil
}

View file

@ -6,6 +6,7 @@ import "github.com/portainer/portainer"
type Migrator struct {
UserService *UserService
EndpointService *EndpointService
EndpointGroupService *EndpointGroupService
ResourceControlService *ResourceControlService
SettingsService *SettingsService
VersionService *VersionService
@ -18,6 +19,7 @@ func NewMigrator(store *Store, version int) *Migrator {
return &Migrator{
UserService: store.UserService,
EndpointService: store.EndpointService,
EndpointGroupService: store.EndpointGroupService,
ResourceControlService: store.ResourceControlService,
SettingsService: store.SettingsService,
VersionService: store.VersionService,
@ -120,6 +122,18 @@ func (m *Migrator) Migrate() error {
}
}
if m.CurrentDBVersion < 12 {
err := m.updateEndpointsToVersion12()
if err != nil {
return err
}
err = m.updateEndpointGroupsToVersion12()
if err != nil {
return err
}
}
err := m.VersionService.StoreDBVersion(portainer.DBVersion)
if err != nil {
return err

71
api/bolt/tag_service.go Normal file
View file

@ -0,0 +1,71 @@
package bolt
import (
"github.com/portainer/portainer"
"github.com/portainer/portainer/bolt/internal"
"github.com/boltdb/bolt"
)
// TagService represents a service for managing tags.
type TagService struct {
store *Store
}
// Tags return an array containing all the tags.
func (service *TagService) Tags() ([]portainer.Tag, error) {
var tags = make([]portainer.Tag, 0)
err := service.store.db.View(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte(tagBucketName))
cursor := bucket.Cursor()
for k, v := cursor.First(); k != nil; k, v = cursor.Next() {
var tag portainer.Tag
err := internal.UnmarshalTag(v, &tag)
if err != nil {
return err
}
tags = append(tags, tag)
}
return nil
})
if err != nil {
return nil, err
}
return tags, nil
}
// CreateTag creates a new tag.
func (service *TagService) CreateTag(tag *portainer.Tag) error {
return service.store.db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte(tagBucketName))
id, _ := bucket.NextSequence()
tag.ID = portainer.TagID(id)
data, err := internal.MarshalTag(tag)
if err != nil {
return err
}
err = bucket.Put(internal.Itob(int(tag.ID)), data)
if err != nil {
return err
}
return nil
})
}
// DeleteTag deletes a tag.
func (service *TagService) DeleteTag(ID portainer.TagID) error {
return service.store.db.Update(func(tx *bolt.Tx) error {
bucket := tx.Bucket([]byte(tagBucketName))
err := bucket.Delete(internal.Itob(int(ID)))
if err != nil {
return err
}
return nil
})
}