-
Notifications
You must be signed in to change notification settings - Fork 602
/
client.go
169 lines (146 loc) · 5.56 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may
// not use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file is distributed
// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.
package data
import (
"path/filepath"
"sync"
"github.com/aws/amazon-ecs-agent/agent/api/container"
"github.com/aws/amazon-ecs-agent/agent/api/task"
"github.com/aws/amazon-ecs-agent/agent/data/transformationfunctions"
"github.com/aws/amazon-ecs-agent/agent/engine/image"
"github.com/aws/amazon-ecs-agent/ecs-agent/api/attachment/resource"
generaldata "github.com/aws/amazon-ecs-agent/ecs-agent/data"
"github.com/aws/amazon-ecs-agent/ecs-agent/modeltransformer"
"github.com/aws/amazon-ecs-agent/ecs-agent/netlib/model/networkinterface"
bolt "go.etcd.io/bbolt"
)
const (
dbName = "agent.db"
dbMode = 0600
containersBucketName = "containers"
tasksBucketName = "tasks"
imagesBucketName = "images"
eniAttachmentsBucketName = "eniattachments"
resAttachmentsBucketName = "resattachments"
metadataBucketName = "metadata"
emptyAgentVersionMsg = "No version info available in boltDB. Either this is a fresh instance, or we were using state file to persist data. Transformer not applicable."
)
var (
dbClient Client
once sync.Once
buckets = []string{
imagesBucketName,
containersBucketName,
tasksBucketName,
eniAttachmentsBucketName,
resAttachmentsBucketName,
metadataBucketName,
}
)
// Client specifies the data management interface to persist and manage various kinds of data in the agent.
type Client interface {
// SaveContainer saves the data of a container.
SaveContainer(*container.Container) error
// SaveDockerContainer saves the data of a docker container.
// We have both SaveContainer and SaveDockerContainer so that a caller who doesn't have docker information
// of the container can save container with SaveContainer, while a caller who wants to save the docker
// information of the container can save it with SaveDockerContainer.
SaveDockerContainer(*container.DockerContainer) error
// DeleteContainer deletes the data of a container.
DeleteContainer(string) error
// GetContainers gets the data of all the containers.
GetContainers() ([]*container.DockerContainer, error)
// SaveTask saves the data of a task.
SaveTask(*task.Task) error
// DeleteTask deletes the data of a task.
DeleteTask(string) error
// GetTasks gets the data of all the tasks.
GetTasks() ([]*task.Task, error)
// SaveImageState saves the data of an image state.
SaveImageState(*image.ImageState) error
// DeleteImageState deletes the data of an image state.
DeleteImageState(string) error
// GetImageStates gets the data of all the image states.
GetImageStates() ([]*image.ImageState, error)
// SaveENIAttachment saves the data of an ENI attachment.
SaveENIAttachment(*networkinterface.ENIAttachment) error
// DeleteENIAttachment deletes the data of an ENI atttachment.
DeleteENIAttachment(string) error
// GetENIAttachments gets the data of all the ENI attachments.
GetENIAttachments() ([]*networkinterface.ENIAttachment, error)
// SaveResourceAttachment saves the data of a resource attachment.
// This includes the EBS Attachment type
SaveResourceAttachment(*resource.ResourceAttachment) error
// DeleteResourceAttachment deletes the data of a resource atttachment.
DeleteResourceAttachment(string) error
// GetResourceAttachments gets the data of all the resouce attachments.
GetResourceAttachments() ([]*resource.ResourceAttachment, error)
// SaveMetadata saves a key value pair of metadata.
SaveMetadata(string, string) error
// GetMetadata gets the value of a certain kind of metadata.
GetMetadata(string) (string, error)
// Close closes the connection to database.
Close() error
}
// client implements the Client interface using boltdb as the backing data store.
type client struct {
generaldata.Client
}
// New returns a data client that implements the Client interface with boltdb.
func New(dataDir string) (Client, error) {
var err error
once.Do(func() {
dbClient, err = setup(dataDir)
})
if err != nil {
return nil, err
}
return dbClient, nil
}
// NewWithSetup returns a data client that implements the Client interface with boltdb.
// It always runs the db setup. Used for testing.
func NewWithSetup(dataDir string) (Client, error) {
return setup(dataDir)
}
// setup initiates the boltdb client and makes sure the buckets we use and transformer are created, and
// registers transformation functions to transformer.
func setup(dataDir string) (*client, error) {
db, err := bolt.Open(filepath.Join(dataDir, dbName), dbMode, nil)
err = db.Update(func(tx *bolt.Tx) error {
for _, b := range buckets {
_, err = tx.CreateBucketIfNotExists([]byte(b))
if err != nil {
return err
}
}
return nil
})
// create transformer
transformer := modeltransformer.NewTransformer()
// registering task transformation functions
transformationfunctions.RegisterTaskTransformationFunctions(transformer)
if err != nil {
return nil, err
}
return &client{
generaldata.Client{
Accessor: generaldata.DBAccessor{},
DB: db,
Transformer: transformer,
},
}, nil
}
// Close closes the boltdb connection.
func (c *client) Close() error {
return c.DB.Close()
}