MyFirstApp: Durability section for gophercloud

Adding the code for interact with the object storage service with go.

Change-Id: I4f994b6f8ccfca0ab858a062c9243c3a66197ddd
This commit is contained in:
Marcela Bonell 2017-02-23 18:33:51 -06:00
parent e4cc768760
commit eca87c81a4
2 changed files with 224 additions and 0 deletions

View File

@ -0,0 +1,158 @@
package main
import (
"bufio"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack"
"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/containers"
"github.com/gophercloud/gophercloud/openstack/objectstorage/v1/objects"
"github.com/gophercloud/gophercloud/pagination"
)
func main() {
// step-1
authOpts, err := openstack.AuthOptionsFromEnv()
if err != nil {
fmt.Println(err)
return
}
provider, err := openstack.AuthenticatedClient(authOpts)
if err != nil {
fmt.Println(err)
return
}
var regionName = os.Getenv("OS_REGION_NAME")
objectClient, err := openstack.NewObjectStorageV1(provider, gophercloud.EndpointOpts{
Region: regionName,
})
if err != nil {
fmt.Println(err)
return
}
// step-2
containerName := "fractals"
containers.Create(objectClient, containerName, nil)
// step-3
containers.List(objectClient, &containers.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
containerList, _ := containers.ExtractNames(page)
for _, name := range containerList {
fmt.Printf("Container name [%s] \n", name)
}
return true, nil
})
// step-4
filePath := "goat.jpg"
objectName := "an amazing goat"
f, _ := os.Open(filePath)
defer f.Close()
reader := bufio.NewReader(f)
options := objects.CreateOpts{
Content: reader,
}
objects.Create(objectClient, containerName, objectName, options)
// step-5
objects.List(objectClient, containerName, &objects.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
objectList, _ := objects.ExtractNames(page)
for _, name := range objectList {
fmt.Printf("Object name [%s] \n", name)
}
return true, nil
})
// step-6
// step-7
// step-8
objects.Delete(objectClient, containerName, objectName, nil)
// step-9
// step-10
containerName = "fractals"
containers.Create(objectClient, containerName, nil)
// step-11
endpoint := "http://IP_API_1"
resp, _ := http.Get(endpoint + "/v1/fractal")
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
type Fractal struct {
UUID string `json:"uuid"`
}
type Data struct {
Results int `json:"num_results"`
Objects []Fractal `json:"objects"`
Page int `json:"page"`
TotalPages int `json:"total_pages"`
}
var data Data
json.Unmarshal([]byte(body), &data)
for _, fractal := range data.Objects {
r, _ := http.Get(endpoint + "/fractal/" + fractal.UUID)
defer r.Body.Close()
image := fractal.UUID + ".png"
out, _ := os.Create(image)
defer out.Close()
io.Copy(out, r.Body)
f, _ := os.Open(image)
defer f.Close()
reader := bufio.NewReader(f)
options := objects.CreateOpts{
Content: reader,
}
objectName = fractal.UUID
fmt.Printf("Uploading object [%s] in container [%s]... \n", objectName, containerName)
objects.Create(objectClient, containerName, objectName, options)
}
objects.List(objectClient, containerName, &objects.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
objectList, _ := objects.ExtractNames(page)
for _, name := range objectList {
fmt.Printf("Object [%s] in container [%s] \n", name, containerName)
}
return true, nil
})
// step-12
objects.List(objectClient, containerName, &objects.ListOpts{}).EachPage(func(page pagination.Page) (bool, error) {
objectList, _ := objects.ExtractNames(page)
for _, name := range objectList {
fmt.Printf("Deleting object [%s] in container [%s]... \n", name, containerName)
objects.Delete(objectClient, containerName, name, nil)
}
return true, nil
})
fmt.Printf("Deleting container [%s] \n", containerName)
containers.Delete(objectClient, containerName)
// step-13
objects.Update(objectClient, containerName, objectName, &objects.UpdateOpts{Metadata: map[string]string{"foo": "bar"}})
// step-14
}

View File

@ -123,6 +123,13 @@ First, learn how to connect to the Object Storage endpoint:
:start-after: step-1 :start-after: step-1
:end-before: step-2 :end-before: step-2
.. only:: gophercloud
.. literalinclude:: ../samples/gophercloud/durability.go
:language: go
:start-after: step-1
:end-before: step-2
To begin to store objects, we must first make a container. To begin to store objects, we must first make a container.
Call yours :code:`fractals`: Call yours :code:`fractals`:
@ -173,6 +180,12 @@ Call yours :code:`fractals`:
u'txc6262b9c2bc1445b9dfe3-00574277ff', u'date': u'Mon, 23 May 2016 u'txc6262b9c2bc1445b9dfe3-00574277ff', u'date': u'Mon, 23 May 2016
03:24:47 GMT', u'content-type': u'text/plain; charset=utf-8'}) 03:24:47 GMT', u'content-type': u'text/plain; charset=utf-8'})
.. only:: gophercloud
.. literalinclude:: ../samples/gophercloud/durability.go
:language: go
:start-after: step-2
:end-before: step-3
You should now be able to see this container appear in a listing of You should now be able to see this container appear in a listing of
all containers in your account: all containers in your account:
@ -219,6 +232,13 @@ all containers in your account:
[Munch({u'count': 0, u'bytes': 0, u'name': u'fractals'}), [Munch({u'count': 0, u'bytes': 0, u'name': u'fractals'}),
Munch({u'count': 0, u'bytes': 0, u'name': u'fractals_segments'})] Munch({u'count': 0, u'bytes': 0, u'name': u'fractals_segments'})]
.. only:: gophercloud
.. literalinclude:: ../samples/gophercloud/durability.go
:language: go
:start-after: step-3
:end-before: step-4
The next logical step is to upload an object. Find a photo of a goat The next logical step is to upload an object. Find a photo of a goat
online, name it :code:`goat.jpg`, and upload it to your online, name it :code:`goat.jpg`, and upload it to your
:code:`fractals` container: :code:`fractals` container:
@ -248,6 +268,13 @@ online, name it :code:`goat.jpg`, and upload it to your
:start-after: step-4 :start-after: step-4
:end-before: step-5 :end-before: step-5
.. only:: gophercloud
.. literalinclude:: ../samples/gophercloud/durability.go
:language: go
:start-after: step-4
:end-before: step-5
List objects in your :code:`fractals` container to see if the upload List objects in your :code:`fractals` container to see if the upload
was successful. Then, download the file to verify that the md5sum is was successful. Then, download the file to verify that the md5sum is
the same: the same:
@ -364,6 +391,13 @@ the same:
d1408b5bf6510426db6e2bafc2f90854 d1408b5bf6510426db6e2bafc2f90854
.. only:: gophercloud
.. literalinclude:: ../samples/gophercloud/durability.go
:language: go
:start-after: step-5
:end-before: step-6
Finally, clean up by deleting the test object: Finally, clean up by deleting the test object:
.. only:: fog .. only:: fog
@ -421,6 +455,12 @@ Finally, clean up by deleting the test object:
[] []
.. only:: gophercloud
.. literalinclude:: ../samples/gophercloud/durability.go
:language: go
:start-after: step-8
:end-before: step-9
Back up the Fractals from the database on the Object Storage Back up the Fractals from the database on the Object Storage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -455,6 +495,13 @@ Place the images in the :code:`fractals` container:
:start-after: step-10 :start-after: step-10
:end-before: step-11 :end-before: step-11
.. only:: gophercloud
.. literalinclude:: ../samples/gophercloud/durability.go
:language: go
:start-after: step-10
:end-before: step-11
Next, back up all existing fractals from the database to the swift container. Next, back up all existing fractals from the database to the swift container.
A simple loop takes care of that: A simple loop takes care of that:
@ -502,6 +549,12 @@ A simple loop takes care of that:
Before you try to run the previous script, make sure that Before you try to run the previous script, make sure that
it is installed on your system. it is installed on your system.
.. only:: gophercloud
.. literalinclude:: ../samples/gophercloud/durability.go
:language: go
:start-after: step-11
:end-before: step-12
Configure the Fractals app to use Object Storage Configure the Fractals app to use Object Storage
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -544,6 +597,13 @@ Otherwise, the delete operation fails:
:start-after: step-12 :start-after: step-12
:end-before: step-13 :end-before: step-13
.. only:: gophercloud
.. literalinclude:: ../samples/gophercloud/durability.go
:language: go
:start-after: step-12
:end-before: step-13
.. warning:: It is not possible to restore deleted objects. Be careful. .. warning:: It is not possible to restore deleted objects. Be careful.
Add metadata to objects Add metadata to objects
@ -598,6 +658,12 @@ your SDK.
:start-after: step-13 :start-after: step-13
:end-before: step-14 :end-before: step-14
.. only:: gophercloud
.. literalinclude:: ../samples/gophercloud/durability.go
:language: go
:start-after: step-13
:end-before: step-14
Large objects Large objects
~~~~~~~~~~~~~ ~~~~~~~~~~~~~