mirror of https://github.com/docker/compose.git
introduce config --services, --volumes, --hash for backward compatibility
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
parent
3366131096
commit
ec5489a08c
|
@ -22,6 +22,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/cnabio/cnab-to-oci/remotes"
|
||||
"github.com/distribution/distribution/v3/reference"
|
||||
|
@ -32,14 +33,18 @@ import (
|
|||
"github.com/docker/compose-cli/api/client"
|
||||
"github.com/docker/compose-cli/api/compose"
|
||||
"github.com/docker/compose-cli/api/config"
|
||||
"github.com/docker/compose-cli/utils"
|
||||
)
|
||||
|
||||
type convertOptions struct {
|
||||
*projectOptions
|
||||
Format string
|
||||
Output string
|
||||
quiet bool
|
||||
resolve bool
|
||||
Format string
|
||||
Output string
|
||||
quiet bool
|
||||
resolve bool
|
||||
services bool
|
||||
volumes bool
|
||||
hash string
|
||||
}
|
||||
|
||||
var addFlagsFuncs []func(cmd *cobra.Command, opts *convertOptions)
|
||||
|
@ -60,6 +65,16 @@ func convertCommand(p *projectOptions) *cobra.Command {
|
|||
}
|
||||
os.Stdout = devnull
|
||||
}
|
||||
if opts.services {
|
||||
return runServices(opts)
|
||||
}
|
||||
if opts.volumes {
|
||||
return runVolumes(opts)
|
||||
}
|
||||
if opts.hash != "" {
|
||||
return runHash(opts)
|
||||
}
|
||||
|
||||
return runConvert(cmd.Context(), opts, args)
|
||||
},
|
||||
}
|
||||
|
@ -68,6 +83,10 @@ func convertCommand(p *projectOptions) *cobra.Command {
|
|||
flags.BoolVar(&opts.resolve, "resolve-image-digests", false, "Pin image tags to digests.")
|
||||
flags.BoolVarP(&opts.quiet, "quiet", "q", false, "Only validate the configuration, don't print anything.")
|
||||
|
||||
flags.BoolVar(&opts.services, "services", false, "Print the service names, one per line.")
|
||||
flags.BoolVar(&opts.volumes, "volumes", false, "Print the volume names, one per line.")
|
||||
flags.StringVar(&opts.hash, "hash", "", "Print the service config hash, one per line.")
|
||||
|
||||
// add flags for hidden backends
|
||||
for _, f := range addFlagsFuncs {
|
||||
f(cmd, &opts)
|
||||
|
@ -126,3 +145,44 @@ func runConvert(ctx context.Context, opts convertOptions, services []string) err
|
|||
_, err = fmt.Fprint(out, string(json))
|
||||
return err
|
||||
}
|
||||
|
||||
func runServices(opts convertOptions) error {
|
||||
project, err := opts.toProject(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range project.Services {
|
||||
fmt.Println(s.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runVolumes(opts convertOptions) error {
|
||||
project, err := opts.toProject(nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, v := range project.Volumes {
|
||||
fmt.Println(v.Name)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func runHash(opts convertOptions) error {
|
||||
var services []string
|
||||
if opts.hash != "*" {
|
||||
services = append(services, strings.Split(opts.hash, ",")...)
|
||||
}
|
||||
project, err := opts.toProject(services)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range project.Services {
|
||||
hash, err := utils.ServiceHash(s)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("%s %s\n", s.Name, hash)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import (
|
|||
"github.com/compose-spec/compose-go/types"
|
||||
moby "github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/filters"
|
||||
|
||||
"github.com/docker/compose-cli/utils"
|
||||
)
|
||||
|
||||
// Containers is a set of moby Container
|
||||
|
@ -69,14 +71,14 @@ type containerPredicate func(c moby.Container) bool
|
|||
func isService(services ...string) containerPredicate {
|
||||
return func(c moby.Container) bool {
|
||||
service := c.Labels[serviceLabel]
|
||||
return contains(services, service)
|
||||
return utils.StringContains(services, service)
|
||||
}
|
||||
}
|
||||
|
||||
func isNotService(services ...string) containerPredicate {
|
||||
return func(c moby.Container) bool {
|
||||
service := c.Labels[serviceLabel]
|
||||
return !contains(services, service)
|
||||
return !utils.StringContains(services, service)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/docker/compose-cli/api/compose"
|
||||
"github.com/docker/compose-cli/api/progress"
|
||||
status "github.com/docker/compose-cli/local/moby"
|
||||
"github.com/docker/compose-cli/utils"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -97,7 +98,7 @@ func (s *composeService) ensureService(ctx context.Context, project *types.Proje
|
|||
return nil
|
||||
}
|
||||
|
||||
expected, err := jsonHash(service)
|
||||
expected, err := utils.ServiceHash(service)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -249,7 +250,7 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
|
|||
// setDependentLifecycle define the Lifecycle strategy for all services to depend on specified service
|
||||
func setDependentLifecycle(project *types.Project, service string, strategy string) {
|
||||
for i, s := range project.Services {
|
||||
if contains(s.GetDependencies(), service) {
|
||||
if utils.StringContains(s.GetDependencies(), service) {
|
||||
if s.Extensions == nil {
|
||||
s.Extensions = map[string]interface{}{}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import (
|
|||
"github.com/docker/compose-cli/api/compose"
|
||||
"github.com/docker/compose-cli/api/progress"
|
||||
convert "github.com/docker/compose-cli/local/moby"
|
||||
"github.com/docker/compose-cli/utils"
|
||||
)
|
||||
|
||||
func (s *composeService) Create(ctx context.Context, project *types.Project, opts compose.CreateOptions) error {
|
||||
|
@ -102,7 +103,7 @@ func (s *composeService) Create(ctx context.Context, project *types.Project, opt
|
|||
prepareNetworkMode(project)
|
||||
|
||||
return InDependencyOrder(ctx, project, func(c context.Context, service types.ServiceConfig) error {
|
||||
if contains(opts.Services, service.Name) {
|
||||
if utils.StringContains(opts.Services, service.Name) {
|
||||
return s.ensureService(c, project, service, opts.Recreate, opts.Inherit, opts.Timeout)
|
||||
}
|
||||
return s.ensureService(c, project, service, opts.RecreateDependencies, opts.Inherit, opts.Timeout)
|
||||
|
@ -121,7 +122,7 @@ func prepareVolumes(p *types.Project) error {
|
|||
p.Services[i].DependsOn = make(types.DependsOnConfig, len(dependServices))
|
||||
}
|
||||
for _, service := range p.Services {
|
||||
if contains(dependServices, service.Name) {
|
||||
if utils.StringContains(dependServices, service.Name) {
|
||||
p.Services[i].DependsOn[service.Name] = types.ServiceDependency{
|
||||
Condition: types.ServiceConditionStarted,
|
||||
}
|
||||
|
@ -196,7 +197,7 @@ func getImageName(service types.ServiceConfig, projectName string) string {
|
|||
func (s *composeService) getCreateOptions(ctx context.Context, p *types.Project, service types.ServiceConfig, number int, inherit *moby.Container,
|
||||
autoRemove bool) (*container.Config, *container.HostConfig, *network.NetworkingConfig, error) {
|
||||
|
||||
hash, err := jsonHash(service)
|
||||
hash, err := utils.ServiceHash(service)
|
||||
if err != nil {
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import (
|
|||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/docker/compose-cli/utils"
|
||||
)
|
||||
|
||||
// ServiceStatus indicates the status of a service
|
||||
|
@ -313,7 +315,7 @@ func (g *Graph) HasCycles() (bool, error) {
|
|||
path := []string{
|
||||
vertex.Key,
|
||||
}
|
||||
if !contains(discovered, vertex.Key) && !contains(finished, vertex.Key) {
|
||||
if !utils.StringContains(discovered, vertex.Key) && !utils.StringContains(finished, vertex.Key) {
|
||||
var err error
|
||||
discovered, finished, err = g.visit(vertex.Key, path, discovered, finished)
|
||||
|
||||
|
@ -331,11 +333,11 @@ func (g *Graph) visit(key string, path []string, discovered []string, finished [
|
|||
|
||||
for _, v := range g.Vertices[key].Children {
|
||||
path := append(path, v.Key)
|
||||
if contains(discovered, v.Key) {
|
||||
if utils.StringContains(discovered, v.Key) {
|
||||
return nil, nil, fmt.Errorf("cycle found: %s", strings.Join(path, " -> "))
|
||||
}
|
||||
|
||||
if !contains(finished, v.Key) {
|
||||
if !utils.StringContains(finished, v.Key) {
|
||||
if _, _, err := g.visit(v.Key, path, discovered, finished); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ func (s *composeService) Logs(ctx context.Context, projectName string, consumer
|
|||
}
|
||||
if len(options.Services) > 0 {
|
||||
ignore = func(s string) bool {
|
||||
return !contains(options.Services, s)
|
||||
return !utils.StringContains(options.Services, s)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,27 +14,21 @@
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compose
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/compose-spec/compose-go/types"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
func jsonHash(o interface{}) (string, error) {
|
||||
// ServiceHash compute configuration has for a service
|
||||
// TODO move this to compose-go
|
||||
func ServiceHash(o types.ServiceConfig) (string, error) {
|
||||
bytes, err := json.Marshal(o)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return digest.SHA256.FromBytes(bytes).String(), nil
|
||||
}
|
||||
|
||||
func contains(slice []string, item string) bool {
|
||||
for _, v := range slice {
|
||||
if v == item {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
return digest.SHA256.FromBytes(bytes).Encoded(), nil
|
||||
}
|
Loading…
Reference in New Issue