diff --git a/internal/common/arch.go b/internal/common/arch.go new file mode 100644 index 0000000..5d2dd90 --- /dev/null +++ b/internal/common/arch.go @@ -0,0 +1,24 @@ +// Copyright 2019 Sorint.lab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License 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 common + +type Arch string + +const ( + Arch386 Arch = "386" + ArchAMD64 Arch = "amd64" + ArchARM Arch = "arm" + ArchARM64 Arch = "arm64" +) diff --git a/internal/common/common.go b/internal/common/common.go new file mode 100644 index 0000000..6ed5494 --- /dev/null +++ b/internal/common/common.go @@ -0,0 +1,127 @@ +// Copyright 2019 Sorint.lab +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License 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 common + +import ( + "io" + "io/ioutil" + "net/url" + "os" + "path" + + "github.com/pkg/errors" + "github.com/sorintlab/agola/internal/etcd" + "github.com/sorintlab/agola/internal/objectstorage" + "github.com/sorintlab/agola/internal/services/config" + "go.uber.org/zap" +) + +const ( + StorePrefix = "agola" +) + +// WriteFileAtomicFunc atomically writes a file, it achieves this by creating a +// temporary file and then moving it. writeFunc is the func that will write +// data to the file. +// This function is taken from +// https://github.com/youtube/vitess/blob/master/go/ioutil2/ioutil.go +// Copyright 2012, Google Inc. BSD-license, see licenses/LICENSE-BSD-3-Clause +func WriteFileAtomicFunc(filename string, perm os.FileMode, writeFunc func(f io.Writer) error) error { + dir, name := path.Split(filename) + f, err := ioutil.TempFile(dir, name) + if err != nil { + return err + } + err = writeFunc(f) + if err == nil { + err = f.Sync() + } + if closeErr := f.Close(); err == nil { + err = closeErr + } + if permErr := os.Chmod(f.Name(), perm); err == nil { + err = permErr + } + if err == nil { + err = os.Rename(f.Name(), filename) + } + // Any err should result in full cleanup. + if err != nil { + os.Remove(f.Name()) + } + return err +} + +// WriteFileAtomic atomically writes a file +func WriteFileAtomic(filename string, data []byte, perm os.FileMode) error { + return WriteFileAtomicFunc(filename, perm, + func(f io.Writer) error { + _, err := f.Write(data) + return err + }) +} + +func NewLTS(c *config.LTS) (*objectstorage.ObjStorage, error) { + var ( + err error + lts objectstorage.Storage + ) + + switch c.Type { + case config.LTSTypePosix: + lts, err = objectstorage.NewPosixStorage(c.Path) + if err != nil { + return nil, errors.Wrapf(err, "failed to create posix object storage") + } + case config.LTSTypeS3: + // minio golang client doesn't accept an url as an endpoint + endpoint := c.Endpoint + secure := !c.DisableTLS + if u, err := url.Parse(c.Endpoint); err == nil { + endpoint = u.Host + switch u.Scheme { + case "https": + secure = true + case "http": + secure = false + default: + return nil, errors.Errorf("wrong s3 endpoint scheme %q (must be http or https)", u.Scheme) + } + } + lts, err = objectstorage.NewS3Storage(c.Bucket, c.Location, endpoint, c.AccessKey, c.SecretAccessKey, secure) + if err != nil { + return nil, errors.Wrapf(err, "failed to create s3 object storage") + } + } + + return objectstorage.NewObjStorage(lts, "/"), nil +} + +func NewEtcd(c *config.Etcd, logger *zap.Logger, prefix string) (*etcd.Store, error) { + e, err := etcd.New(etcd.Config{ + Logger: logger, + Endpoints: c.Endpoints, + Prefix: prefix, + CertFile: c.TLSCertFile, + KeyFile: c.TLSKeyFile, + CAFile: c.TLSCAFile, + SkipTLSVerify: c.TLSSkipVerify, + }) + if err != nil { + return nil, errors.Wrap(err, "failed to create etcd store") + } + + return e, nil +}