4 "github.com/minio/minio-go/v6"
5 "bpa-restapi-agent/internal/config"
11 type MinIOInfo struct {
12 minioC *minio.Client `json:"minio client"`
15 // Initialize the MinIO server, create buckets
16 func Initialize() (MinIOInfo, error) {
17 endpoint := config.GetConfiguration().MinIOAddress + ":" + config.GetConfiguration().MinIOPort
18 accessKeyID := config.GetConfiguration().AccessKeyID
19 secretAccessKey := config.GetConfiguration().SecretAccessKey
22 minioInfo := MinIOInfo{}
23 // Initialize minio client object.
24 minioClient, err := minio.New(endpoint, accessKeyID, secretAccessKey, useSSL)
31 bucketNames := []string{"binary", "container", "operatingsystem"}
32 location := "us-west-1"
34 for _, bucketName := range bucketNames {
35 err := minioClient.MakeBucket(bucketName, location)
37 // Check to see if we already own this bucket (which happens if you run this twice)
38 exists, errBucketExists := minioClient.BucketExists(bucketName)
39 if errBucketExists == nil && exists {
40 log.Printf("We already own %s\n", bucketName)
46 log.Printf("Successfully created %s\n", bucketName)
50 minioInfo.minioC = minioClient
54 func (m MinIOInfo) PutImage(bucketName string, objName string, localPath string) (int64, error) {
56 //contentType := "multipart/form-data"
57 contentType := "application/octet-stream"
59 // Upload the zip file with FPutObject
60 n, err := m.minioC.FPutObject(bucketName, objName, localPath, minio.PutObjectOptions{ContentType:contentType})
66 fileInfo, _ := os.Stat(localPath)
67 fileSize := fileInfo.Size()
69 if n != int64(fileSize) {
70 log.Printf("FPutObject failed %s of size %d\n", objName, n)
74 log.Printf("Successfully uploaded %s of size %d\n", objName, n)
78 func (m MinIOInfo) PatchImage(bucketName string, objName string, localPath string, offset int64, objSize int64) (int64, error) {
82 tempFile, err := os.Open(localPath)
88 defer tempFile.Close()
90 if _, err := tempFile.Seek(offset, 0); err != nil {
91 log.Printf("PatchImage seek %s failed: %s", tempFile.Name(), err)
95 objInfo, err := m.minioC.StatObject(bucketName, objName, minio.StatObjectOptions{})
99 } else if objInfo.Size != offset || objInfo.Size == 0 {
103 var objNameTemp = objName
105 objNameTemp = objName + ".tmp"
108 contentType := "application/octet-stream"
109 n, err = m.minioC.PutObject(bucketName, objNameTemp, tempFile, objSize, minio.PutObjectOptions{ContentType:contentType})
116 log.Printf("PatchImage PutObject %s failed with bytes: %d", tempFile.Name(), n)
121 src1 := minio.NewSourceInfo(bucketName, objName, nil)
122 src2 := minio.NewSourceInfo(bucketName, objNameTemp, nil)
123 srcs := []minio.SourceInfo{src1, src2}
125 dst, err := minio.NewDestinationInfo(bucketName, objName, nil, nil)
127 log.Printf("NewDestinationInfo failed", err)
131 // There is issue, the last src should be the smallest obj size
132 err = m.minioC.ComposeObject(dst, srcs)
134 log.Printf("ComposeObject failed", err)
139 log.Printf("Successfully PatchImage %s of size %d\n", objName, n)
143 func (m MinIOInfo) DeleteImage(bucketName string, objName string) (error) {
145 err := m.minioC.RemoveObject(bucketName, objName)
147 log.Printf("MinIO Remove object %s failed\n", bucketName)
154 func (m MinIOInfo) CleanupImages(bucketName string) (error) {
155 // create a done channel to control 'ListObjectsV2' go routine.
156 doneCh := make(chan struct{})
159 for objCh := range m.minioC.ListObjectsV2(bucketName, "", true, doneCh) {
160 if objCh.Err != nil {
164 err := m.minioC.RemoveObject(bucketName, objCh.Key)
170 for objPartInfo := range m.minioC.ListIncompleteUploads(bucketName, "", true, doneCh) {
171 if objPartInfo.Err != nil {
172 return objPartInfo.Err
174 if objPartInfo.Key != "" {
175 err := m.minioC.RemoveIncompleteUpload(bucketName, objPartInfo.Key)