func (storage *PublishedStorage) Remove(path string) error {
	err := storage.conn.ObjectDelete(storage.container, filepath.Join(storage.prefix, path))
	if err != nil {
		return fmt.Errorf("error deleting %s from %s: %s", path, storage, err)
	}
	return nil
}
Remove removes single file under public path
package swift
import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"time"
	"github.com/aptly-dev/aptly/aptly"
	"github.com/aptly-dev/aptly/utils"
	"github.com/ncw/swift"
	"github.com/pkg/errors"
)
type PublishedStorage struct {
	conn              *swift.Connection
	container         string
	prefix            string
	supportBulkDelete bool
}
type swiftInfo map[string]interface{}
var (
	_ aptly.PublishedStorage = (*PublishedStorage)(nil)
)
func NewPublishedStorage(username string, password string, authURL string, tenant string, tenantID string, domain string, domainID string, tenantDomain string, tenantDomainID string, container string, prefix string) (*PublishedStorage, error) {
	if username == "" {
		if username = os.Getenv("OS_USERNAME"); username == "" {
			username = os.Getenv("ST_USER")
		}
	}
	if password == "" {
		if password = os.Getenv("OS_PASSWORD"); password == "" {
			password = os.Getenv("ST_KEY")
		}
	}
	if authURL == "" {
		if authURL = os.Getenv("OS_AUTH_URL"); authURL == "" {
			authURL = os.Getenv("ST_AUTH")
		}
	}
	if tenant == "" {
		tenant = os.Getenv("OS_TENANT_NAME")
	}
	if tenantID == "" {
		tenantID = os.Getenv("OS_TENANT_ID")
	}
	if domain == "" {
		domain = os.Getenv("OS_USER_DOMAIN_NAME")
	}
	if domainID == "" {
		domainID = os.Getenv("OS_USER_DOMAIN_ID")
	}
	if tenantDomain == "" {
		tenantDomain = os.Getenv("OS_PROJECT_DOMAIN")
	}
	if tenantDomainID == "" {
		tenantDomainID = os.Getenv("OS_PROJECT_DOMAIN_ID")
	}
	ct := &swift.Connection{
		UserName:       username,
		ApiKey:         password,
		AuthUrl:        authURL,
		UserAgent:      "aptly/" + aptly.Version,
		Tenant:         tenant,
		TenantId:       tenantID,
		Domain:         domain,
		DomainId:       domainID,
		TenantDomain:   tenantDomain,
		TenantDomainId: tenantDomainID,
		ConnectTimeout: 60 * time.Second,
		Timeout:        60 * time.Second,
	}
	err := ct.Authenticate()
	if err != nil {
		return nil, fmt.Errorf("swift authentication failed: %s", err)
	}
	var bulkDelete bool
	resp, err := http.Get(filepath.Join(ct.StorageUrl, "..", "..") + "/info")
	if err == nil {
		defer resp.Body.Close()
		decoder := json.NewDecoder(resp.Body)
		var infos swiftInfo
		if decoder.Decode(&infos) == nil {
			_, bulkDelete = infos["bulk_delete"]
		}
	}
	result := &PublishedStorage{
		conn:              ct,
		container:         container,
		prefix:            prefix,
		supportBulkDelete: bulkDelete,
	}
	return result, nil
}
func (storage *PublishedStorage) String() string {
	return fmt.Sprintf("Swift: %s/%s/%s", storage.conn.StorageUrl, storage.container, storage.prefix)
}
func (storage *PublishedStorage) MkDir(path string) error {
	return nil
}
func (storage *PublishedStorage) PutFile(path string, sourceFilename string) error {
	var (
		source *os.File
		err    error
	)
	source, err = os.Open(sourceFilename)
	if err != nil {
		return err
	}
	defer source.Close()
	err = storage.putFile(path, source)
	if err != nil {
		err = errors.Wrap(err, fmt.Sprintf("error uploading %s to %s", sourceFilename, storage))
	}
	return err
}
func (storage *PublishedStorage) putFile(path string, source io.Reader) error {
	_, err := storage.conn.ObjectPut(storage.container, filepath.Join(storage.prefix, path), source, false, "", "", nil)
	return err
}