├── docs └── start.png ├── os ├── os_linux.go ├── os_windows.go ├── os_darwin.go └── os.go ├── acceptance ├── privileged │ ├── fixture │ │ ├── Gemfile │ │ ├── Gemfile.lock │ │ └── config.ru │ ├── proxy │ │ └── proxy_suite_test.go │ └── privileged_suite_test.go ├── help_test.go └── acceptance_suite_test.go ├── pkg ├── servicew │ ├── acceptance │ │ ├── fixtures │ │ │ ├── simple-linux.yml │ │ │ └── simple-darwin.yml │ │ ├── integration_suite_test.go │ │ └── integration_test.go │ ├── config │ │ └── config.go │ ├── program │ │ ├── program_suite_test.go │ │ └── program_test.go │ └── main.go ├── cfdevd │ ├── cmd │ │ ├── cmd_suite_test.go │ │ ├── add_ip_alias.go │ │ ├── unimplemented.go │ │ ├── uninstall.go │ │ ├── cmd.go │ │ ├── remove_ip_alias.go │ │ ├── mocks │ │ │ ├── launchd.go │ │ │ └── daemonrunner.go │ │ ├── unimplemented_test.go │ │ └── cmd_test.go │ ├── client │ │ ├── client_suite_test.go │ │ ├── client.go │ │ └── client_test.go │ ├── privileged │ │ └── cfdevd_suite_test.go │ ├── networkd │ │ ├── privileged │ │ │ └── privileged_suite_test.go │ │ └── ip_aliaser.go │ ├── handshake.go │ └── install.go └── analyticsd │ ├── integration │ └── integration_suite_test.go │ ├── config │ └── service_whitelist.go │ ├── cloud_controller │ └── cloud_controller_suite_test.go │ ├── command │ ├── app_crash.go │ ├── org_create.go │ ├── app_restage.go │ ├── route_create.go │ ├── space_create.go │ ├── service_broker_create.go │ ├── user_provided_service_create.go │ ├── command_suite_test.go │ ├── app_create.go │ ├── service_create.go │ ├── service_bind.go │ ├── mocks │ │ └── cloud_controller_client.go │ ├── org_create_test.go │ ├── route_create_test.go │ ├── space_create_test.go │ ├── app_crash_test.go │ ├── service_broker_create_test.go │ └── app_create_test.go │ ├── segment │ ├── client.go │ └── mocks │ │ └── analytics.go │ ├── daemon │ ├── mocks │ │ └── analytics.go │ └── daemon.go │ └── main.go ├── daemon ├── listeners_linux.go ├── listeners_windows.go ├── launchd_suite_test.go ├── spec.go ├── listeners_darwin.go └── servicew_linux.go ├── driver ├── ip.go ├── hyperkit │ ├── safekill_linux.go │ ├── safekill_windows.go │ ├── hyperkit_suite_test.go │ ├── safekill_darwin.go │ ├── network.go │ └── safekill_darwin_test.go ├── utils.go ├── constants.go ├── kvm │ └── network.go ├── hyperv │ ├── hyperv_suite_test.go │ ├── mocks │ │ └── runner.go │ └── requirements.go └── ip_linux.go ├── cmd ├── bosh │ ├── bosh_suite_test.go │ └── mocks │ │ ├── ui.go │ │ └── analytics_client.go ├── stop │ ├── stop_suite_test.go │ ├── mocks │ │ ├── host.go │ │ ├── process_manager.go │ │ ├── network.go │ │ ├── analytics.go │ │ ├── vpnkit.go │ │ ├── analyticsd.go │ │ ├── linuxkit.go │ │ ├── launchd.go │ │ └── cfdevd_client.go │ └── stop.go ├── start │ ├── start_suite_test.go │ └── mocks │ │ ├── cfdevd.go │ │ ├── os.go │ │ ├── host.go │ │ ├── stop.go │ │ ├── cache.go │ │ ├── provisioner.go │ │ ├── provision.go │ │ ├── network.go │ │ ├── isoreader.go │ │ ├── env.go │ │ ├── ui.go │ │ ├── vpnkit.go │ │ ├── system-profiler.go │ │ ├── analyticsd.go │ │ └── analytics_client.go ├── provision │ ├── provision_suite_test.go │ └── mocks │ │ ├── metadata_reader.go │ │ └── ui.go ├── telemetry │ └── telemetry_suite_test.go ├── deploy-service │ ├── deploy_service_suite_test.go │ └── mocks │ │ ├── metadata_reader.go │ │ ├── analytics.go │ │ └── ui.go ├── root_linux.go ├── root_darwin.go ├── root_windows.go ├── catalog │ └── catalog.go ├── version │ ├── version_suite_test.go │ └── mocks │ │ └── metadata.go └── download │ └── download.go ├── errors ├── errors_suite_test.go ├── errors.go └── errors_test.go ├── resource ├── retry │ ├── retry_suite_test.go │ ├── retry.go │ └── retry_test.go ├── progress │ ├── progress_suite_test.go │ └── progress.go ├── resource_suite_test.go ├── catalog.go └── catalog_test.go ├── config ├── config_suite_test.go ├── semver.go ├── semver_test.go ├── proxy.go └── proxy_test.go ├── cfanalytics ├── toggle │ ├── toggle_suite_test.go │ └── toggle.go ├── cfanalytics_suite_test.go ├── analyticsd_linux.go ├── analyticsd_windows.go ├── analyticsd.go ├── analyticsd_darwin.go └── mocks │ ├── ui.go │ └── analytics_client.go ├── provision ├── provision_suite_test.go ├── controller.go ├── progress.go └── mocks │ └── runner.go ├── workspace ├── workspace_suite_test.go └── metadata_test.go ├── runner ├── sudo.go ├── powershell.go └── bosh.go ├── .gitignore ├── NOTICE ├── scripts ├── generate-plugin-windows.ps1 ├── generate-plugin.sh ├── run-docker-tests.ps1 ├── meow.sh └── run-docker-tests.sh └── CONTRIBUTING.md /docs/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloudfoundry-attic/cfdev/HEAD/docs/start.png -------------------------------------------------------------------------------- /os/os_linux.go: -------------------------------------------------------------------------------- 1 | package os 2 | 3 | func (o *OS) Version() (string, error) { 4 | return "", nil 5 | } -------------------------------------------------------------------------------- /acceptance/privileged/fixture/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'roda' 4 | gem 'mysql2' 5 | gem 'sequel' 6 | -------------------------------------------------------------------------------- /pkg/servicew/acceptance/fixtures/simple-linux.yml: -------------------------------------------------------------------------------- 1 | --- 2 | label: org.cfdev.servicew.simple 3 | executable: sleep 4 | args: 5 | - "12345" -------------------------------------------------------------------------------- /daemon/listeners_linux.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import "net" 4 | 5 | func Listeners(name string) ([]net.Listener, error) { 6 | return nil, nil 7 | } 8 | -------------------------------------------------------------------------------- /daemon/listeners_windows.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import "net" 4 | 5 | func Listeners(name string) ([]net.Listener, error) { 6 | return nil, nil 7 | } 8 | -------------------------------------------------------------------------------- /pkg/servicew/acceptance/fixtures/simple-darwin.yml: -------------------------------------------------------------------------------- 1 | --- 2 | label: org.cfdev.servicew.simple 3 | executable: sleep 4 | args: 5 | - "12345" 6 | options: 7 | UserService: true -------------------------------------------------------------------------------- /driver/ip.go: -------------------------------------------------------------------------------- 1 | // +build !linux 2 | 3 | package driver 4 | 5 | import "code.cloudfoundry.org/cfdev/config" 6 | 7 | func IP(cfg config.Config) (string, error) { 8 | return "127.0.0.1", nil 9 | } 10 | -------------------------------------------------------------------------------- /driver/hyperkit/safekill_linux.go: -------------------------------------------------------------------------------- 1 | package hyperkit 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | func SafeKill(pidfile, name string) error { 9 | return fmt.Errorf("SafeKill not implemented for %s", runtime.GOOS) 10 | } -------------------------------------------------------------------------------- /driver/hyperkit/safekill_windows.go: -------------------------------------------------------------------------------- 1 | package hyperkit 2 | 3 | import ( 4 | "fmt" 5 | "runtime" 6 | ) 7 | 8 | func SafeKill(pidfile, name string) error { 9 | return fmt.Errorf("SafeKill not implemented for %s", runtime.GOOS) 10 | } -------------------------------------------------------------------------------- /pkg/servicew/config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | type Config struct { 4 | Args []string 5 | Env map[string]string 6 | Executable string 7 | Label string 8 | Log string 9 | Options map[string]interface{} 10 | } 11 | -------------------------------------------------------------------------------- /cmd/bosh/bosh_suite_test.go: -------------------------------------------------------------------------------- 1 | package bosh_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestBosh(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Cmd Bosh Suite") 13 | } 14 | -------------------------------------------------------------------------------- /cmd/stop/stop_suite_test.go: -------------------------------------------------------------------------------- 1 | package stop_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestStop(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Cmd Stop Suite") 13 | } 14 | -------------------------------------------------------------------------------- /cmd/start/start_suite_test.go: -------------------------------------------------------------------------------- 1 | package start_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestStart(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Cmd Start Suite") 13 | } 14 | -------------------------------------------------------------------------------- /errors/errors_suite_test.go: -------------------------------------------------------------------------------- 1 | package errors_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestErrors(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Errors Suite") 13 | } 14 | -------------------------------------------------------------------------------- /resource/retry/retry_suite_test.go: -------------------------------------------------------------------------------- 1 | package retry_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestRetry(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Retry Suite") 13 | } 14 | -------------------------------------------------------------------------------- /config/config_suite_test.go: -------------------------------------------------------------------------------- 1 | package config_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestConfig(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "cf dev - config suite") 13 | } 14 | -------------------------------------------------------------------------------- /cfanalytics/toggle/toggle_suite_test.go: -------------------------------------------------------------------------------- 1 | package toggle_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestToggle(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Toggle Suite") 13 | } 14 | -------------------------------------------------------------------------------- /cmd/provision/provision_suite_test.go: -------------------------------------------------------------------------------- 1 | package provision_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestProvision(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Provision Suite") 13 | } 14 | -------------------------------------------------------------------------------- /driver/hyperkit/hyperkit_suite_test.go: -------------------------------------------------------------------------------- 1 | package hyperkit_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestHyperkit(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Hyperkit Suite") 13 | } 14 | -------------------------------------------------------------------------------- /provision/provision_suite_test.go: -------------------------------------------------------------------------------- 1 | package provision_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestProvision(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Provision Suite") 13 | } 14 | -------------------------------------------------------------------------------- /resource/progress/progress_suite_test.go: -------------------------------------------------------------------------------- 1 | package progress_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestProgress(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Progress Suite") 13 | } 14 | -------------------------------------------------------------------------------- /resource/resource_suite_test.go: -------------------------------------------------------------------------------- 1 | package resource_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestResource(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "cf dev - resource suite") 13 | } 14 | -------------------------------------------------------------------------------- /workspace/workspace_suite_test.go: -------------------------------------------------------------------------------- 1 | package workspace_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestWorkspace(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Workspace Suite") 13 | } 14 | -------------------------------------------------------------------------------- /cmd/telemetry/telemetry_suite_test.go: -------------------------------------------------------------------------------- 1 | package telemetry_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestTelemetry(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Cmd Telemetry Suite") 13 | } 14 | -------------------------------------------------------------------------------- /pkg/cfdevd/cmd/cmd_suite_test.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package cmd_test 4 | 5 | import ( 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | 9 | "testing" 10 | ) 11 | 12 | func TestCmd(t *testing.T) { 13 | RegisterFailHandler(Fail) 14 | RunSpecs(t, "Cmd Suite") 15 | } 16 | -------------------------------------------------------------------------------- /cfanalytics/cfanalytics_suite_test.go: -------------------------------------------------------------------------------- 1 | package cfanalytics_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "testing" 8 | ) 9 | 10 | func TestCfanalytics(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Cfanalytics Suite") 13 | } 14 | -------------------------------------------------------------------------------- /pkg/servicew/program/program_suite_test.go: -------------------------------------------------------------------------------- 1 | package program_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestProgram(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "ServiceWrapper Program Suite") 13 | } 14 | -------------------------------------------------------------------------------- /os/os_windows.go: -------------------------------------------------------------------------------- 1 | package os 2 | 3 | import ( 4 | "os/exec" 5 | "strings" 6 | ) 7 | 8 | func (o *OS) Version() (string, error) { 9 | output, err := exec.Command("powershell.exe", "-Command", "[System.Environment]::OSVersion.VersionString").Output() 10 | return strings.TrimSpace(string(output)), err 11 | } -------------------------------------------------------------------------------- /pkg/analyticsd/integration/integration_suite_test.go: -------------------------------------------------------------------------------- 1 | package integration 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestIntegration(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Integration Suite") 13 | } 14 | -------------------------------------------------------------------------------- /pkg/cfdevd/client/client_suite_test.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package client_test 4 | 5 | import ( 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | 9 | "testing" 10 | ) 11 | 12 | func TestClient(t *testing.T) { 13 | RegisterFailHandler(Fail) 14 | RunSpecs(t, "Client Suite") 15 | } 16 | -------------------------------------------------------------------------------- /cmd/deploy-service/deploy_service_suite_test.go: -------------------------------------------------------------------------------- 1 | package deploy_service 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestDeployService(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Cmd Deploy Service Suite") 13 | } 14 | -------------------------------------------------------------------------------- /pkg/cfdevd/privileged/cfdevd_suite_test.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package privileged_test 4 | 5 | import ( 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | 9 | "testing" 10 | ) 11 | 12 | func TestTcpbinder(t *testing.T) { 13 | RegisterFailHandler(Fail) 14 | RunSpecs(t, "Cfdevd Suite") 15 | } 16 | -------------------------------------------------------------------------------- /pkg/analyticsd/config/service_whitelist.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | var ( 4 | SERVICE_WHITELIST = []string{ 5 | "mysql", "p-mysql", "p.mysql", 6 | "rabbit", "rabbitmq", "p-rabbitmq", "p.rabbitmq", 7 | "redis", "p-redis", "p.redis", 8 | "p-circuit-breaker-dashboard", "p-config-server", "p-service-registry", 9 | } 10 | ) 11 | -------------------------------------------------------------------------------- /acceptance/privileged/fixture/Gemfile.lock: -------------------------------------------------------------------------------- 1 | GEM 2 | remote: https://rubygems.org/ 3 | specs: 4 | mysql2 (0.5.1) 5 | rack (2.0.5) 6 | roda (3.8.0) 7 | rack 8 | sequel (5.8.0) 9 | 10 | PLATFORMS 11 | ruby 12 | 13 | DEPENDENCIES 14 | mysql2 15 | roda 16 | sequel 17 | 18 | BUNDLED WITH 19 | 1.16.1 20 | -------------------------------------------------------------------------------- /pkg/analyticsd/cloud_controller/cloud_controller_suite_test.go: -------------------------------------------------------------------------------- 1 | package cloud_controller_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCloudController(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "CloudController Suite") 13 | } 14 | -------------------------------------------------------------------------------- /daemon/launchd_suite_test.go: -------------------------------------------------------------------------------- 1 | package daemon_test 2 | 3 | import ( 4 | "math/rand" 5 | "time" 6 | 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | 10 | "testing" 11 | ) 12 | 13 | func TestDaemon(t *testing.T) { 14 | RegisterFailHandler(Fail) 15 | RunSpecs(t, "Daemon Suite") 16 | } 17 | 18 | var _ = BeforeSuite(func() { 19 | rand.Seed(time.Now().UnixNano()) 20 | }) 21 | -------------------------------------------------------------------------------- /runner/sudo.go: -------------------------------------------------------------------------------- 1 | package runner 2 | 3 | import ( 4 | "os" 5 | "os/exec" 6 | ) 7 | 8 | type Sudo struct{} 9 | 10 | func (s *Sudo) Run(args ...string) error { 11 | var ( 12 | invocation = append([]string{"-S"}, args...) 13 | cmd = exec.Command("sudo", invocation...) 14 | ) 15 | 16 | cmd.Stdout = os.Stdout 17 | cmd.Stderr = os.Stderr 18 | cmd.Stdin = os.Stdin 19 | return cmd.Run() 20 | } 21 | -------------------------------------------------------------------------------- /acceptance/privileged/proxy/proxy_suite_test.go: -------------------------------------------------------------------------------- 1 | package proxy_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestPrivileged(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "cf dev - acceptance proxy - privileged suite") 13 | } 14 | 15 | var _ = BeforeSuite(func() { 16 | SetDefaultEventuallyTimeout(5 * time.Minute) 17 | }) 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | .DS_Store 13 | 14 | # editors 15 | .idea 16 | 17 | /bin/ 18 | 19 | *.iso 20 | *.img 21 | **/*-state 22 | 23 | !**/start/fixtures/cf-deps.iso 24 | 25 | cfdev 26 | cfdvd 27 | analytix 28 | temp 29 | tmp 30 | 31 | -------------------------------------------------------------------------------- /runner/powershell.go: -------------------------------------------------------------------------------- 1 | package runner 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | ) 7 | 8 | type Powershell struct{} 9 | 10 | func (p *Powershell) Output(command string) (string, error) { 11 | output, err := exec.Command("powershell.exe", "-Command", command).CombinedOutput() 12 | if err != nil { 13 | return "", fmt.Errorf("failed to execute: powershell.exe -Command %q: %s: %s", command, err, output) 14 | } 15 | 16 | return string(output), nil 17 | } 18 | -------------------------------------------------------------------------------- /daemon/spec.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | type DaemonSpec struct { 4 | Label string 5 | EnvironmentVariables map[string]string 6 | Program string 7 | ProgramArguments []string 8 | SessionType string 9 | RunAtLoad bool 10 | Sockets map[string]string 11 | StdoutPath string 12 | StderrPath string 13 | LogPath string 14 | Options map[string]interface{} 15 | } 16 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-Present CloudFoundry.org Foundation, Inc. All Rights Reserved. 2 | 3 | This product is licensed to you under the Apache License, Version 2.0 (the "License"). 4 | You may not use this product except in compliance with the License. 5 | 6 | This product may include a number of subcomponents with separate copyright notices 7 | and license terms. Your use of these subcomponents is subject to the terms and 8 | conditions of the subcomponent's license, as noted in the LICENSE file. 9 | -------------------------------------------------------------------------------- /pkg/cfdevd/cmd/add_ip_alias.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "net" 5 | 6 | "code.cloudfoundry.org/cfdev/pkg/cfdevd/networkd" 7 | ) 8 | 9 | type AddIPAliasCommand struct { 10 | } 11 | 12 | func (u *AddIPAliasCommand) Execute(conn *net.UnixConn) error { 13 | hostNet := &networkd.HostNetD{} 14 | 15 | err := hostNet.AddLoopbackAliases(BOSH_IP, GOROUTER_IP) 16 | if err == nil { 17 | conn.Write([]byte{0}) 18 | } else { 19 | conn.Write([]byte{1}) 20 | } 21 | 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /os/os_darwin.go: -------------------------------------------------------------------------------- 1 | package os 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | "strings" 7 | ) 8 | 9 | func (o *OS) Version() (string, error) { 10 | name, err := exec.Command("sw_vers", "-productName").Output() 11 | if err != nil { 12 | return "", err 13 | } 14 | 15 | version, err := exec.Command("sw_vers", "-productVersion").Output() 16 | if err != nil { 17 | return "", err 18 | } 19 | 20 | return fmt.Sprintf("%s %s", strings.TrimSpace(string(name)), strings.TrimSpace(string(version))), nil 21 | } -------------------------------------------------------------------------------- /cmd/root_linux.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | "code.cloudfoundry.org/cfdev/daemon" 6 | "code.cloudfoundry.org/cfdev/driver" 7 | "code.cloudfoundry.org/cfdev/driver/kvm" 8 | ) 9 | 10 | func newDaemonRunner(config config.Config) driver.DaemonRunner { 11 | return daemon.NewServiceWrapper(config) 12 | } 13 | 14 | func newDriver(ui UI, config config.Config) driver.Driver { 15 | daemonRunner := newDaemonRunner(config) 16 | 17 | return kvm.New(config, daemonRunner, ui) 18 | } -------------------------------------------------------------------------------- /os/os.go: -------------------------------------------------------------------------------- 1 | package os 2 | 3 | import "github.com/cloudfoundry/gosigar" 4 | 5 | const bytesInMegabyte = 1048576 6 | 7 | type Stats struct { 8 | AvailableMemory uint64 9 | TotalMemory uint64 10 | } 11 | 12 | type OS struct{} 13 | 14 | func (o *OS) Stats() (Stats, error) { 15 | mem := &sigar.Mem{} 16 | if err := mem.Get(); err != nil { 17 | return Stats{}, err 18 | } 19 | 20 | return Stats{ 21 | AvailableMemory: mem.ActualFree / bytesInMegabyte, 22 | TotalMemory: mem.Total / bytesInMegabyte, 23 | }, nil 24 | } 25 | -------------------------------------------------------------------------------- /driver/utils.go: -------------------------------------------------------------------------------- 1 | package driver 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | "encoding/json" 6 | "io/ioutil" 7 | "path/filepath" 8 | ) 9 | 10 | func WriteHttpConfig(cfg config.Config) error { 11 | var ( 12 | httpProxyPath = filepath.Join(cfg.VpnKitStateDir, "http_proxy.json") 13 | proxyConfig = cfg.BuildProxyConfig() 14 | proxyContents, _ = json.Marshal(proxyConfig) 15 | httpProxyConfig = []byte(proxyContents) 16 | ) 17 | 18 | return ioutil.WriteFile(httpProxyPath, httpProxyConfig, 0600) 19 | } 20 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/app_crash.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | ) 9 | 10 | type AppCrash struct { 11 | CCClient CloudControllerClient 12 | AnalyticsClient *segment.Client 13 | Logger *log.Logger 14 | } 15 | 16 | func (c *AppCrash) HandleResponse(body json.RawMessage) error { 17 | err := c.AnalyticsClient.Enqueue("app push failed", nil) 18 | 19 | if err != nil { 20 | return fmt.Errorf("failed to send analytics: %v", err) 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/org_create.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | ) 9 | 10 | type OrgCreate struct { 11 | CCClient CloudControllerClient 12 | AnalyticsClient *segment.Client 13 | Logger *log.Logger 14 | } 15 | 16 | func (c *OrgCreate) HandleResponse(body json.RawMessage) error { 17 | err := c.AnalyticsClient.Enqueue("org created", nil) 18 | 19 | if err != nil { 20 | return fmt.Errorf("failed to send analytics: %v", err) 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/app_restage.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | ) 9 | 10 | type AppRestage struct { 11 | CCClient CloudControllerClient 12 | AnalyticsClient *segment.Client 13 | Logger *log.Logger 14 | } 15 | 16 | func (c *AppRestage) HandleResponse(body json.RawMessage) error { 17 | err := c.AnalyticsClient.Enqueue("app restage", nil) 18 | 19 | if err != nil { 20 | return fmt.Errorf("failed to send analytics: %v", err) 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/route_create.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | ) 9 | 10 | type RouteCreate struct { 11 | CCClient CloudControllerClient 12 | AnalyticsClient *segment.Client 13 | Logger *log.Logger 14 | } 15 | 16 | func (c *RouteCreate) HandleResponse(body json.RawMessage) error { 17 | err := c.AnalyticsClient.Enqueue("created route", nil) 18 | 19 | if err != nil { 20 | return fmt.Errorf("failed to send analytics: %v", err) 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/space_create.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | ) 9 | 10 | type SpaceCreate struct { 11 | CCClient CloudControllerClient 12 | AnalyticsClient *segment.Client 13 | Logger *log.Logger 14 | } 15 | 16 | func (c *SpaceCreate) HandleResponse(body json.RawMessage) error { 17 | err := c.AnalyticsClient.Enqueue("space created", nil) 18 | 19 | if err != nil { 20 | return fmt.Errorf("failed to send analytics: %v", err) 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /pkg/cfdevd/cmd/unimplemented.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "io" 8 | "net" 9 | ) 10 | 11 | type UnimplementedCommand struct { 12 | Instruction uint8 13 | Logger io.Writer 14 | } 15 | 16 | func (u *UnimplementedCommand) Execute(conn *net.UnixConn) error { 17 | message := []byte{uint8(33)} 18 | fmt.Fprintf(u.Logger, "Unimplemented command: %v\n", u.Instruction) 19 | if _, err := conn.Write(message); err != nil { 20 | return fmt.Errorf("unimplememted instruction: failed to write error code to connection: %s", err) 21 | } 22 | return nil 23 | } 24 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/service_broker_create.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | ) 9 | 10 | type ServiceBrokerCreate struct { 11 | CCClient CloudControllerClient 12 | AnalyticsClient *segment.Client 13 | Logger *log.Logger 14 | } 15 | 16 | func (c *ServiceBrokerCreate) HandleResponse(body json.RawMessage) error { 17 | err := c.AnalyticsClient.Enqueue( "created service broker", nil) 18 | 19 | if err != nil { 20 | return fmt.Errorf("failed to send analytics: %v", err) 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /pkg/cfdevd/cmd/uninstall.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package cmd 4 | 5 | import ( 6 | "net" 7 | ) 8 | 9 | //go:generate mockgen -package mocks -destination mocks/daemonrunner.go code.cloudfoundry.org/cfdevd/cmd DaemonRunner 10 | type DaemonRunner interface { 11 | RemoveDaemon(string) error 12 | } 13 | 14 | type UninstallCommand struct { 15 | DaemonRunner DaemonRunner 16 | } 17 | 18 | func (u *UninstallCommand) Execute(conn *net.UnixConn) error { 19 | err := u.DaemonRunner.RemoveDaemon("org.cloudfoundry.cfdevd") 20 | if err == nil { 21 | conn.Write([]byte{0}) 22 | } else { 23 | conn.Write([]byte{1}) 24 | } 25 | return err 26 | } 27 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/user_provided_service_create.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | ) 9 | 10 | type UserProvidedServiceCreate struct { 11 | CCClient CloudControllerClient 12 | AnalyticsClient *segment.Client 13 | Logger *log.Logger 14 | } 15 | 16 | func (c *UserProvidedServiceCreate) HandleResponse(body json.RawMessage) error { 17 | err := c.AnalyticsClient.Enqueue("created user provided service", nil) 18 | 19 | if err != nil { 20 | return fmt.Errorf("failed to send analytics: %v", err) 21 | } 22 | 23 | return nil 24 | } 25 | -------------------------------------------------------------------------------- /resource/catalog.go: -------------------------------------------------------------------------------- 1 | package resource 2 | 3 | type Catalog struct { 4 | Items []Item 5 | } 6 | 7 | type Item struct { 8 | URL string 9 | Name string 10 | MD5 string 11 | Size uint64 12 | InUse bool 13 | } 14 | 15 | func (c *Catalog) Lookup(name string) *Item { 16 | for index := range c.Items { 17 | item := &c.Items[index] 18 | if item.Name == name { 19 | return item 20 | } 21 | } 22 | return nil 23 | } 24 | 25 | func (c *Catalog) Remove(name string) { 26 | newItems := make([]Item, 0, len(c.Items)) 27 | for _, item := range c.Items { 28 | if item.Name != name { 29 | newItems = append(newItems, item) 30 | } 31 | } 32 | c.Items = newItems 33 | } 34 | -------------------------------------------------------------------------------- /cmd/root_darwin.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | "code.cloudfoundry.org/cfdev/daemon" 6 | "code.cloudfoundry.org/cfdev/driver" 7 | "code.cloudfoundry.org/cfdev/driver/hyperkit" 8 | cfdevdClient "code.cloudfoundry.org/cfdev/pkg/cfdevd/client" 9 | ) 10 | 11 | func newDaemonRunner(config config.Config) driver.DaemonRunner { 12 | return daemon.New(config.StateDir) 13 | } 14 | 15 | func newDriver(ui UI, config config.Config) driver.Driver { 16 | var ( 17 | daemonRunner = newDaemonRunner(config) 18 | cfdevd = cfdevdClient.New("CFD3V", config.CFDevDSocketPath) 19 | ) 20 | 21 | return hyperkit.New(config, daemonRunner, ui, cfdevd) 22 | } 23 | -------------------------------------------------------------------------------- /errors/errors.go: -------------------------------------------------------------------------------- 1 | package errors 2 | 3 | type safeError struct { 4 | err error 5 | msg string 6 | } 7 | 8 | func SafeWrap(err error, msg string) error { 9 | return &safeError{ 10 | err: err, 11 | msg: msg, 12 | } 13 | } 14 | 15 | func (se *safeError) Error() string { 16 | if se.err == nil { 17 | return se.msg 18 | } 19 | return se.msg + ": " + se.err.Error() 20 | } 21 | 22 | func (se *safeError) safeError() string { 23 | if e, ok := se.err.(*safeError); ok { 24 | return se.msg + ": " + e.safeError() 25 | } 26 | return se.msg 27 | } 28 | 29 | func SafeError(err error) string { 30 | if e, ok := err.(*safeError); ok { 31 | return e.safeError() 32 | } 33 | return "" 34 | } 35 | -------------------------------------------------------------------------------- /cmd/root_windows.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | "code.cloudfoundry.org/cfdev/daemon" 6 | "code.cloudfoundry.org/cfdev/driver" 7 | "code.cloudfoundry.org/cfdev/driver/hyperv" 8 | "code.cloudfoundry.org/cfdev/runner" 9 | ) 10 | 11 | func newDaemonRunner(config config.Config) driver.DaemonRunner { 12 | return daemon.NewWinSW(config.CFDevHome) 13 | } 14 | 15 | func newDriver(ui UI, config config.Config) driver.Driver { 16 | daemonRunner := newDaemonRunner(config) 17 | 18 | return hyperv.New( 19 | config, 20 | daemonRunner, 21 | ui, 22 | &runner.Powershell{}, 23 | "7207f451-2ca3-4b88-8d01-820a21d78293", 24 | "cc2a519a-fb40-4e45-a9f1-c7f04c5ad7fa", 25 | "e3ae8f06-8c25-47fb-b6ed-c20702bcef5e", 26 | ) 27 | } 28 | -------------------------------------------------------------------------------- /driver/constants.go: -------------------------------------------------------------------------------- 1 | package driver 2 | 3 | import "code.cloudfoundry.org/cfdev/daemon" 4 | 5 | const ( 6 | VMName = "cfdev" 7 | VpnKitLabel = "org.cloudfoundry.cfdev.vpnkit" 8 | LinuxKitLabel = "org.cloudfoundry.cfdev.linuxkit" 9 | ContainerSubnet = "10.144.0.0/16" 10 | ) 11 | 12 | type UI interface { 13 | Say(message string, args ...interface{}) 14 | } 15 | 16 | type DaemonRunner interface { 17 | AddDaemon(daemon.DaemonSpec) error 18 | RemoveDaemon(string) error 19 | Start(string) error 20 | Stop(string) error 21 | IsRunning(string) (bool, error) 22 | } 23 | 24 | type Driver interface { 25 | CheckRequirements() error 26 | Prestart() error 27 | Start(cpus int, memory int, efiPath string) error 28 | Stop() error 29 | IsRunning() (bool, error) 30 | } -------------------------------------------------------------------------------- /pkg/analyticsd/command/command_suite_test.go: -------------------------------------------------------------------------------- 1 | package command_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/command/mocks" 5 | "encoding/json" 6 | "github.com/golang/mock/gomock" 7 | "net/url" 8 | "testing" 9 | 10 | . "github.com/onsi/ginkgo" 11 | . "github.com/onsi/gomega" 12 | ) 13 | 14 | func TestCommand(t *testing.T) { 15 | RegisterFailHandler(Fail) 16 | RunSpecs(t, "Command Suite") 17 | } 18 | 19 | func MatchFetch(mockCCClient *mocks.MockCloudControllerClient, expectedPath, result string) { 20 | mockCCClient.EXPECT().Fetch(gomock.Any(), gomock.Any(), gomock.Any()).Do(func(path string, params url.Values, dest interface{}) error { 21 | Expect(path).To(Equal(expectedPath)) 22 | return json.Unmarshal([]byte(result), dest) 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /acceptance/privileged/fixture/config.ru: -------------------------------------------------------------------------------- 1 | require 'open-uri' 2 | require 'roda' 3 | require 'sequel' 4 | 5 | 6 | class App < Roda 7 | route do |r| 8 | r.root do 9 | 'Hello, world!' 10 | end 11 | r.get 'external' do 12 | open('http://example.com').read 13 | end 14 | r.get 'external_https' do 15 | open('https://example.com').read 16 | end 17 | r.get 'external_no_proxy' do 18 | open('http://google.com').read 19 | end 20 | r.get 'host' do 21 | open('http://host.cfdev.sh:'+ENV['HOST_SERVER_PORT']).read 22 | end 23 | r.get 'mysql' do 24 | db = Sequel.connect(ENV['DATABASE_URL']) 25 | "Versions: #{db.fetch('SHOW VARIABLES LIKE "%version%"').all}\n" 26 | end 27 | end 28 | end 29 | 30 | run App.freeze.app 31 | -------------------------------------------------------------------------------- /cmd/catalog/catalog.go: -------------------------------------------------------------------------------- 1 | package catalog 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "code.cloudfoundry.org/cfdev/config" 7 | "code.cloudfoundry.org/cfdev/errors" 8 | "github.com/spf13/cobra" 9 | ) 10 | 11 | type UI interface { 12 | Say(message string, args ...interface{}) 13 | } 14 | 15 | type Catalog struct { 16 | UI UI 17 | Config config.Config 18 | } 19 | 20 | func (c *Catalog) Cmd() *cobra.Command { 21 | return &cobra.Command{ 22 | Use: "catalog", 23 | RunE: c.RunE, 24 | } 25 | } 26 | 27 | func (c *Catalog) RunE(cmd *cobra.Command, args []string) error { 28 | bytes, err := json.MarshalIndent(c.Config.Dependencies, "", " ") 29 | if err != nil { 30 | return errors.SafeWrap(err, "unable to marshal catalog") 31 | } 32 | c.UI.Say(string(bytes)) 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /runner/bosh.go: -------------------------------------------------------------------------------- 1 | package runner 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | "code.cloudfoundry.org/cfdev/workspace" 6 | "os" 7 | "os/exec" 8 | "path/filepath" 9 | "runtime" 10 | ) 11 | 12 | type Bosh struct { 13 | config config.Config 14 | workspace *workspace.Workspace 15 | } 16 | 17 | func NewBosh(config config.Config) *Bosh { 18 | return &Bosh{ 19 | config: config, 20 | workspace: workspace.New(config), 21 | } 22 | } 23 | 24 | func (b *Bosh) Output(args ...string) ([]byte, error) { 25 | executable := filepath.Join(b.config.BinaryDir, "bosh") 26 | 27 | if runtime.GOOS == "windows" { 28 | executable += ".exe" 29 | } 30 | 31 | command := exec.Command(executable, args...) 32 | command.Env = append(os.Environ(), b.workspace.Envs()...) 33 | return command.Output() 34 | } 35 | -------------------------------------------------------------------------------- /config/semver.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | type Version struct { 9 | Major int 10 | Minor int 11 | Build int 12 | Original string 13 | } 14 | 15 | func NewSemver(v string) (*Version, error) { 16 | s := &Version{Original: v} 17 | arr := strings.SplitN(v, ".", 3) 18 | var err error 19 | if len(arr) >= 1 && v != "" { 20 | s.Major, err = strconv.Atoi(arr[0]) 21 | if err != nil { 22 | return nil, err 23 | } 24 | } 25 | if len(arr) >= 2 { 26 | s.Minor, err = strconv.Atoi(arr[1]) 27 | if err != nil { 28 | return nil, err 29 | } 30 | } 31 | if len(arr) >= 3 { 32 | parts := strings.SplitN(arr[2], "-", 2) 33 | s.Build, err = strconv.Atoi(parts[0]) 34 | if err != nil { 35 | return nil, err 36 | } 37 | } 38 | return s, nil 39 | } 40 | -------------------------------------------------------------------------------- /pkg/cfdevd/networkd/privileged/privileged_suite_test.go: -------------------------------------------------------------------------------- 1 | package privileged_test 2 | 3 | import ( 4 | "os/exec" 5 | "testing" 6 | "time" 7 | 8 | . "github.com/onsi/ginkgo" 9 | . "github.com/onsi/gomega" 10 | "github.com/onsi/gomega/gexec" 11 | ) 12 | 13 | func TestPrivileged(t *testing.T) { 14 | RegisterFailHandler(Fail) 15 | RunSpecs(t, "cf dev - network - privileged suite") 16 | } 17 | 18 | var _ = BeforeSuite(func() { 19 | SetDefaultEventuallyTimeout(10 * time.Second) 20 | Expect(HasSudoPrivilege()).To(BeTrue(), "Please run 'sudo echo hi' first") 21 | 22 | }) 23 | 24 | func HasSudoPrivilege() bool { 25 | cmd := exec.Command("sh", "-c", "sudo -n true") 26 | session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 27 | Expect(err).NotTo(HaveOccurred()) 28 | Eventually(session).Should(gexec.Exit()) 29 | 30 | if session.ExitCode() == 0 { 31 | return true 32 | } 33 | return false 34 | } 35 | -------------------------------------------------------------------------------- /resource/retry/retry.go: -------------------------------------------------------------------------------- 1 | package retry 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "time" 7 | ) 8 | 9 | func Retry(fn func() error, shouldRetry func(error) bool) error { 10 | for { 11 | err := fn() 12 | if err == nil { 13 | return nil 14 | } else if !shouldRetry(err) { 15 | return err 16 | } 17 | } 18 | } 19 | 20 | type retryable struct { 21 | err error 22 | } 23 | 24 | func (e *retryable) Error() string { 25 | return e.err.Error() 26 | } 27 | 28 | func WrapAsRetryable(err error) error { 29 | return &retryable{err} 30 | } 31 | 32 | func Retryable(retries int, sleep time.Duration, writer io.Writer) func(error) bool { 33 | counter := 0 34 | return func(e error) bool { 35 | counter++ 36 | _, isRetry := e.(*retryable) 37 | if isRetry && counter < retries { 38 | if writer != nil { 39 | fmt.Fprintf(writer, "\n------- Failed: Retrying: %d -----\n", counter) 40 | } 41 | time.Sleep(sleep) 42 | return true 43 | } 44 | return false 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /pkg/cfdevd/cmd/cmd.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package cmd 4 | 5 | import ( 6 | "encoding/binary" 7 | "io" 8 | "net" 9 | "os" 10 | 11 | "code.cloudfoundry.org/cfdev/daemon" 12 | ) 13 | 14 | type Command interface { 15 | Execute(*net.UnixConn) error 16 | } 17 | 18 | const UninstallType = uint8(1) 19 | const RemoveIPAliasType = uint8(2) 20 | const AddIPAliasType = uint8(3) 21 | const BindType = uint8(6) 22 | 23 | func UnmarshalCommand(conn io.Reader) (Command, error) { 24 | var instr uint8 25 | binary.Read(conn, binary.LittleEndian, &instr) 26 | 27 | switch instr { 28 | case BindType: 29 | return UnmarshalBindCommand(conn) 30 | case UninstallType: 31 | return &UninstallCommand{ 32 | DaemonRunner: daemon.New(""), 33 | }, nil 34 | case RemoveIPAliasType: 35 | return &RemoveIPAliasCommand{}, nil 36 | case AddIPAliasType: 37 | return &AddIPAliasCommand{}, nil 38 | default: 39 | return &UnimplementedCommand{ 40 | Instruction: instr, 41 | Logger: os.Stdout, 42 | }, nil 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /acceptance/help_test.go: -------------------------------------------------------------------------------- 1 | package acceptance 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | "os/exec" 7 | 8 | "github.com/onsi/gomega/gbytes" 9 | "github.com/onsi/gomega/gexec" 10 | ) 11 | 12 | var _ = Describe("help", func() { 13 | It("running 'cf dev' provides help", func() { 14 | cmd := exec.Command("cf", "dev") 15 | session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 16 | Expect(err).ToNot(HaveOccurred()) 17 | 18 | Eventually(session).Should(gexec.Exit(0)) 19 | Expect(session).To(gbytes.Say("Usage:")) 20 | Expect(session).To(gbytes.Say("Available Commands:")) 21 | }) 22 | 23 | It("running 'cf dev help' provides help", func() { 24 | cmd := exec.Command("cf", "dev", "help") 25 | session, err := gexec.Start(cmd, GinkgoWriter, GinkgoWriter) 26 | Expect(err).ToNot(HaveOccurred()) 27 | 28 | Eventually(session).Should(gexec.Exit(0)) 29 | Expect(session).To(gbytes.Say("Usage:")) 30 | Expect(session).To(gbytes.Say("Available Commands:")) 31 | }) 32 | }) 33 | -------------------------------------------------------------------------------- /pkg/servicew/acceptance/integration_suite_test.go: -------------------------------------------------------------------------------- 1 | package acceptance_test 2 | 3 | import ( 4 | "github.com/onsi/gomega/gexec" 5 | "os/exec" 6 | "path/filepath" 7 | "testing" 8 | 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | ) 12 | 13 | var binaryPath string 14 | 15 | func TestIntegration(t *testing.T) { 16 | RegisterFailHandler(Fail) 17 | RunSpecs(t, "ServiceWrapper Integration Suite") 18 | } 19 | 20 | var _ = BeforeSuite(func() { 21 | var err error 22 | binaryPath, err = gexec.Build("code.cloudfoundry.org/cfdev/pkg/servicew") 23 | Expect(err).NotTo(HaveOccurred()) 24 | }) 25 | 26 | var _ = AfterSuite(func() { 27 | gexec.CleanupBuildArtifacts() 28 | }) 29 | 30 | func run(executable string, args ...string) string { 31 | command := exec.Command(executable, args...) 32 | output, err := command.CombinedOutput() 33 | Expect(err).NotTo(HaveOccurred(), string(output)) 34 | return string(output) 35 | } 36 | 37 | func fixturePath(name string) string { 38 | return filepath.Join("fixtures", name) 39 | } -------------------------------------------------------------------------------- /cfanalytics/analyticsd_linux.go: -------------------------------------------------------------------------------- 1 | package cfanalytics 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/daemon" 5 | "os" 6 | "path" 7 | "path/filepath" 8 | ) 9 | 10 | func (a *AnalyticsD) DaemonSpec() daemon.DaemonSpec { 11 | var ( 12 | proxyConfig = a.Config.BuildProxyConfig() 13 | environmentVariables = map[string]string{ 14 | "CFDEV_MODE": os.Getenv("CFDEV_MODE"), 15 | } 16 | ) 17 | 18 | if proxyConfig.Http != "" { 19 | environmentVariables["HTTP_PROXY"] = proxyConfig.Http 20 | } 21 | if proxyConfig.Https != "" { 22 | environmentVariables["HTTPS_PROXY"] = proxyConfig.Https 23 | } 24 | if proxyConfig.NoProxy != "" { 25 | environmentVariables["NO_PROXY"] = proxyConfig.NoProxy 26 | } 27 | 28 | return daemon.DaemonSpec{ 29 | Label: AnalyticsDLabel, 30 | Program: filepath.Join(a.Config.CacheDir, "analyticsd"), 31 | ProgramArguments: []string{}, 32 | EnvironmentVariables: environmentVariables, 33 | LogPath: path.Join(a.Config.LogDir, "analyticsd.log"), 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /config/semver_test.go: -------------------------------------------------------------------------------- 1 | package config_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | . "github.com/onsi/ginkgo" 6 | . "github.com/onsi/gomega" 7 | ) 8 | 9 | var _ = Describe("Semver", func() { 10 | It("parses 1.2.3", func() { 11 | s, err := config.NewSemver("1.2.3") 12 | Expect(err).NotTo(HaveOccurred()) 13 | Expect(s.Major).To(Equal(1)) 14 | Expect(s.Minor).To(Equal(2)) 15 | Expect(s.Build).To(Equal(3)) 16 | Expect(s.Original).To(Equal("1.2.3")) 17 | }) 18 | 19 | It("parses 2.3.4-patch-1", func() { 20 | s, err := config.NewSemver("2.3.4-patch-1") 21 | Expect(err).NotTo(HaveOccurred()) 22 | Expect(s.Major).To(Equal(2)) 23 | Expect(s.Minor).To(Equal(3)) 24 | Expect(s.Build).To(Equal(4)) 25 | Expect(s.Original).To(Equal("2.3.4-patch-1")) 26 | }) 27 | 28 | It("parses empty string", func() { 29 | s, err := config.NewSemver("") 30 | Expect(err).NotTo(HaveOccurred()) 31 | Expect(s.Major).To(Equal(0)) 32 | Expect(s.Minor).To(Equal(0)) 33 | Expect(s.Build).To(Equal(0)) 34 | Expect(s.Original).To(Equal("")) 35 | }) 36 | }) 37 | -------------------------------------------------------------------------------- /scripts/generate-plugin-windows.ps1: -------------------------------------------------------------------------------- 1 | $cache_dir="$HOME\.cfdev\cache" 2 | 3 | $pkg="code.cloudfoundry.org/cfdev/config" 4 | $cfdepsUrl="C:\Users\pivotal\.cfdev\cache\cfdev-deps.tgz" 5 | $cfAnalyticsdUrl="$PWD\analytix.exe" 6 | 7 | $date=(Get-Date -Format FileDate) 8 | 9 | go build -ldflags ` 10 | "-X main.version=0.0.$date 11 | -X main.testAnalyticsKey=WFz4dVFXZUxN2Y6MzfUHJNWtlgXuOYV2" ` 12 | -o $cfAnalyticsdUrl ` 13 | code.cloudfoundry.org/cfdev/pkg/analyticsd 14 | 15 | go build -ldflags ` 16 | "-X $pkg.analyticsdUrl=$cfAnalyticsdUrl 17 | -X $pkg.analyticsdMd5=$((Get-FileHash $cfAnalyticsdUrl -Algorithm MD5).Hash.ToLower()) 18 | -X $pkg.analyticsdSize=$((Get-Item $cfAnalyticsdUrl).length) 19 | 20 | -X $pkg.cfdepsUrl=$cfdepsUrl 21 | -X $pkg.cfdepsMd5=$((Get-FileHash $cfdepsUrl -Algorithm MD5).Hash.ToLower()) 22 | -X $pkg.cfdepsSize=$((Get-Item $cfdepsUrl).length) 23 | 24 | -X $pkg.cliVersion=0.0.$date 25 | -X $pkg.buildVersion=dev 26 | -X $pkg.testAnalyticsKey=WFz4dVFXZUxN2Y6MzfUHJNWtlgXuOYV2" ` 27 | code.cloudfoundry.org/cfdev 28 | -------------------------------------------------------------------------------- /driver/hyperkit/safekill_darwin.go: -------------------------------------------------------------------------------- 1 | package hyperkit 2 | 3 | /* 4 | #include 5 | */ 6 | import "C" 7 | 8 | import ( 9 | "io/ioutil" 10 | "os" 11 | "strconv" 12 | "strings" 13 | "syscall" 14 | "unsafe" 15 | ) 16 | 17 | func SafeKill(pidfile, name string) error { 18 | data, err := ioutil.ReadFile(pidfile) 19 | if os.IsNotExist(err) { 20 | return nil 21 | } 22 | if err != nil { 23 | return err 24 | } 25 | pid, err := strconv.Atoi(string(data)) 26 | if err != nil { 27 | return err 28 | } 29 | 30 | path, err := executablePath(pid) 31 | if err != nil { 32 | return err 33 | } 34 | 35 | if strings.Contains(path, name) { 36 | syscall.Kill(pid, syscall.SIGKILL) 37 | } 38 | return os.Remove(pidfile) 39 | } 40 | 41 | func executablePath(pid int) (string, error) { 42 | var pathbuf [C.PROC_PIDPATHINFO_MAXSIZE]byte 43 | n := C.proc_pidpath(C.int(pid), unsafe.Pointer(&pathbuf), C.PROC_PIDPATHINFO_MAXSIZE) 44 | if n == 0 { 45 | return "", nil 46 | } else if n <= 0 { 47 | return "", syscall.ENOMEM 48 | } 49 | return string(pathbuf[:n]), nil 50 | } 51 | -------------------------------------------------------------------------------- /cfanalytics/analyticsd_windows.go: -------------------------------------------------------------------------------- 1 | package cfanalytics 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/daemon" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | func (a *AnalyticsD) DaemonSpec() daemon.DaemonSpec { 10 | var ( 11 | proxyConfig = a.Config.BuildProxyConfig() 12 | environmentVariables = map[string]string{ 13 | "CFDEV_MODE": os.Getenv("CFDEV_MODE"), 14 | } 15 | ) 16 | 17 | if proxyConfig.Http != "" { 18 | environmentVariables["HTTP_PROXY"] = proxyConfig.Http 19 | } 20 | if proxyConfig.Https != "" { 21 | environmentVariables["HTTPS_PROXY"] = proxyConfig.Https 22 | } 23 | if proxyConfig.NoProxy != "" { 24 | environmentVariables["NO_PROXY"] = proxyConfig.NoProxy 25 | } 26 | 27 | return daemon.DaemonSpec{ 28 | Label: AnalyticsDLabel, 29 | Program: filepath.Join(a.Config.CacheDir, "analyticsd.exe"), 30 | SessionType: "Background", 31 | ProgramArguments: []string{}, 32 | EnvironmentVariables: environmentVariables, 33 | StdoutPath: filepath.Join(a.Config.LogDir, "analyticsd.stdout.log"), 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /cfanalytics/analyticsd.go: -------------------------------------------------------------------------------- 1 | package cfanalytics 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | "code.cloudfoundry.org/cfdev/daemon" 6 | ) 7 | 8 | const AnalyticsDLabel = "org.cloudfoundry.cfdev.cfanalyticsd" 9 | 10 | type AnalyticsD struct { 11 | Config config.Config 12 | DaemonRunner DaemonRunner 13 | } 14 | 15 | type DaemonRunner interface { 16 | AddDaemon(daemon.DaemonSpec) error 17 | RemoveDaemon(string) error 18 | Start(string) error 19 | Stop(string) error 20 | IsRunning(string) (bool, error) 21 | } 22 | 23 | func (a *AnalyticsD) Start() error { 24 | spec := a.DaemonSpec() 25 | 26 | err := a.DaemonRunner.AddDaemon(spec) 27 | if err != nil { 28 | return err 29 | } 30 | 31 | return a.DaemonRunner.Start(AnalyticsDLabel) 32 | } 33 | 34 | func (a *AnalyticsD) Stop() error { 35 | var reterr error 36 | if err := a.DaemonRunner.Stop(AnalyticsDLabel); err != nil { 37 | reterr = err 38 | } 39 | return reterr 40 | } 41 | 42 | func (a *AnalyticsD) Destroy() error { 43 | return a.DaemonRunner.RemoveDaemon(AnalyticsDLabel) 44 | } 45 | 46 | func (a *AnalyticsD) IsRunning() (bool, error) { 47 | return a.DaemonRunner.IsRunning(AnalyticsDLabel) 48 | } 49 | -------------------------------------------------------------------------------- /provision/controller.go: -------------------------------------------------------------------------------- 1 | package provision 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | "code.cloudfoundry.org/cfdev/driver" 6 | "code.cloudfoundry.org/cfdev/workspace" 7 | "context" 8 | "github.com/aemengo/bosh-runc-cpi/client" 9 | "io" 10 | "time" 11 | ) 12 | 13 | type UI interface { 14 | Say(message string, args ...interface{}) 15 | Writer() io.Writer 16 | } 17 | 18 | type Controller struct { 19 | Config config.Config 20 | Workspace *workspace.Workspace 21 | } 22 | 23 | func NewController(config config.Config) *Controller { 24 | return &Controller{ 25 | Config: config, 26 | Workspace: workspace.New(config), 27 | } 28 | } 29 | 30 | func (c *Controller) Ping(duration time.Duration) error { 31 | var ( 32 | ticker = time.NewTicker(time.Second) 33 | timeout = time.After(duration) 34 | err error 35 | ) 36 | 37 | for { 38 | select { 39 | case <-ticker.C: 40 | var ip string 41 | ip, err = driver.IP(c.Config) 42 | if err != nil { 43 | continue 44 | } 45 | 46 | err = client.Ping(context.Background(), ip+":9999") 47 | if err == nil { 48 | return nil 49 | } 50 | case <-timeout: 51 | return err 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /driver/kvm/network.go: -------------------------------------------------------------------------------- 1 | package kvm 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/driver" 5 | "os/exec" 6 | ) 7 | 8 | // consider moving to more native go implementation 9 | // rather than shelling out 10 | func (d *KVM) setupNetworking(tapDevice, bridge string) { 11 | d.SudoShell.Run("ip", "tuntap", "add", "dev", tapDevice, "mode", "tap") 12 | d.SudoShell.Run("ip", "link", "set", tapDevice, "master", bridge) 13 | d.SudoShell.Run("ip", "link", "set", "dev", bridge, "up") 14 | d.SudoShell.Run("ip", "link", "set", "dev", tapDevice, "up") 15 | } 16 | 17 | func (d *KVM) setupRoutes(ip string) { 18 | d.SudoShell.Run("ip", "route", "add", driver.ContainerSubnet, "via", ip) 19 | } 20 | 21 | func (d *KVM) teardownRoutes() { 22 | d.SudoShell.Run("ip", "route", "flush", driver.ContainerSubnet) 23 | } 24 | 25 | func (d *KVM) teardownNetworking(tapDevice string) { 26 | if d.tapDeviceExists(tapDevice) { 27 | d.SudoShell.Run("ip", "link", "set", "dev", tapDevice, "down") 28 | d.SudoShell.Run("ip", "link", "del", "dev", tapDevice) 29 | } 30 | } 31 | 32 | func (d *KVM) tapDeviceExists(tapDevice string) bool { 33 | err := exec.Command("ip", "link", "show", tapDevice).Run() 34 | return err == nil 35 | } 36 | -------------------------------------------------------------------------------- /daemon/listeners_darwin.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | // #include 4 | // int launch_activate_socket(const char *name, int **fds, size_t *cnt); 5 | import "C" 6 | 7 | import ( 8 | "fmt" 9 | "net" 10 | "os" 11 | "unsafe" 12 | ) 13 | 14 | func Listeners(name string) ([]net.Listener, error) { 15 | files, err := files(name) 16 | if err != nil { 17 | return nil, err 18 | } 19 | 20 | listeners := make([]net.Listener, len(files), len(files)) 21 | for i, file := range files { 22 | if listener, err := net.FileListener(file); err != nil { 23 | return nil, err 24 | } else { 25 | listeners[i] = listener 26 | } 27 | } 28 | 29 | return listeners, nil 30 | } 31 | 32 | func files(name string) ([]*os.File, error) { 33 | var fds *C.int 34 | cnt := C.size_t(0) 35 | 36 | err := C.launch_activate_socket(C.CString(name), &fds, &cnt) 37 | if err != 0 { 38 | return nil, fmt.Errorf("error activating launchd socket %s: %d", name, err) 39 | } 40 | 41 | ptr := unsafe.Pointer(fds) 42 | defer C.free(ptr) 43 | arr := (*[10]C.int)(ptr) 44 | 45 | files := make([]*os.File, int(cnt), int(cnt)) 46 | for i := 0; i < int(cnt) && i < 10; i++ { 47 | files[i] = os.NewFile(uintptr(int(arr[i])), "") 48 | } 49 | 50 | return files, nil 51 | } 52 | -------------------------------------------------------------------------------- /provision/progress.go: -------------------------------------------------------------------------------- 1 | package provision 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/workspace" 5 | "fmt" 6 | "time" 7 | 8 | "code.cloudfoundry.org/cfdev/errors" 9 | ) 10 | 11 | func (c *Controller) report(start time.Time, ui UI, b *Bosh, service workspace.Service, errChan chan error) error { 12 | ticker := time.NewTicker(5 * time.Second) 13 | 14 | for { 15 | select { 16 | case err := <-errChan: 17 | if err != nil { 18 | return errors.SafeWrap(err, fmt.Sprintf("Failed to deploy %s", service.Name)) 19 | } 20 | 21 | ui.Writer().Write([]byte(fmt.Sprintf("\r\033[K Done (%s)\n", time.Now().Sub(start).Round(time.Second)))) 22 | return nil 23 | case <-ticker.C: 24 | p := b.GetVMProgress(start, service.Deployment, service.IsErrand) 25 | 26 | switch p.State { 27 | case Preparing: 28 | ui.Writer().Write([]byte(fmt.Sprintf("\r\033[K Preparing deployment (%s)", p.Duration.Round(time.Second)))) 29 | case Deploying: 30 | ui.Writer().Write([]byte(fmt.Sprintf("\r\033[K Progress: %d of %d (%s)", p.Done, p.Total, p.Duration.Round(time.Second)))) 31 | case RunningErrand: 32 | ui.Writer().Write([]byte(fmt.Sprintf("\r\033[K Running errand (%s)", p.Duration.Round(time.Second)))) 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /cfanalytics/analyticsd_darwin.go: -------------------------------------------------------------------------------- 1 | package cfanalytics 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/daemon" 5 | "os" 6 | "path" 7 | "path/filepath" 8 | ) 9 | 10 | func (a *AnalyticsD) DaemonSpec() daemon.DaemonSpec { 11 | var ( 12 | proxyConfig = a.Config.BuildProxyConfig() 13 | environmentVariables = map[string]string{ 14 | "CFDEV_MODE": os.Getenv("CFDEV_MODE"), 15 | } 16 | ) 17 | 18 | if proxyConfig.Http != "" { 19 | environmentVariables["HTTP_PROXY"] = proxyConfig.Http 20 | } 21 | if proxyConfig.Https != "" { 22 | environmentVariables["HTTPS_PROXY"] = proxyConfig.Https 23 | } 24 | if proxyConfig.NoProxy != "" { 25 | environmentVariables["NO_PROXY"] = proxyConfig.NoProxy 26 | } 27 | 28 | return daemon.DaemonSpec{ 29 | Label: AnalyticsDLabel, 30 | Program: filepath.Join(a.Config.CacheDir, "analyticsd"), 31 | SessionType: "Background", 32 | ProgramArguments: []string{filepath.Join(a.Config.CacheDir, "analyticsd")}, 33 | EnvironmentVariables: environmentVariables, 34 | RunAtLoad: false, 35 | StdoutPath: path.Join(a.Config.LogDir, "analyticsd.stdout.log"), 36 | StderrPath: path.Join(a.Config.LogDir, "analyticsd.stderr.log"), 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pkg/cfdevd/handshake.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package main 4 | 5 | import ( 6 | "encoding/binary" 7 | "fmt" 8 | "io" 9 | "net" 10 | ) 11 | 12 | type Handshake struct { 13 | Magic string 14 | Version uint32 15 | Commit string 16 | } 17 | 18 | func unmarshalHandshake(data []byte) Handshake { 19 | return Handshake{ 20 | Magic: string(data[0:5]), 21 | Version: binary.LittleEndian.Uint32(data[5:9]), 22 | Commit: string(data[9:40]), 23 | } 24 | } 25 | 26 | func marshalHandshake(hsk Handshake) []byte { 27 | data := []byte(hsk.Magic) 28 | data = append(data, make([]byte, 4, 4)...) 29 | binary.LittleEndian.PutUint32(data[5:], hsk.Version) 30 | return append(data, []byte(hsk.Commit)...) 31 | } 32 | 33 | func doHandshake(conn net.Conn) error { 34 | init := make([]byte, 49, 49) 35 | _, err := io.ReadFull(conn, init) 36 | if err != nil { 37 | return err 38 | } 39 | handshake := unmarshalHandshake(init) 40 | fmt.Printf("connection received from client: Name: %s, Version: %d, Commit: %s \n", 41 | handshake.Magic, 42 | handshake.Version, 43 | handshake.Commit, 44 | ) 45 | 46 | conn.Write(marshalHandshake( 47 | Handshake{ 48 | Magic: "CFD3V", 49 | Version: 22, 50 | Commit: "0123456789012345678901234567890123456789", 51 | }, 52 | )) 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /driver/hyperv/hyperv_suite_test.go: -------------------------------------------------------------------------------- 1 | package hyperv_test 2 | 3 | import ( 4 | "io" 5 | "io/ioutil" 6 | "net/http" 7 | "os" 8 | "path/filepath" 9 | "testing" 10 | 11 | . "github.com/onsi/ginkgo" 12 | . "github.com/onsi/gomega" 13 | ) 14 | 15 | func TestHyperv(t *testing.T) { 16 | RegisterFailHandler(Fail) 17 | RunSpecs(t, "Hyperv Suite") 18 | } 19 | 20 | var assetDir string 21 | 22 | var _ = BeforeSuite(func() { 23 | testIsoUrl := "https://s3.amazonaws.com/cfdev-test-assets/test.iso" 24 | testVHDUrl := "https://s3.amazonaws.com/cfdev-test-assets/test-hd.vhdx" 25 | 26 | var err error 27 | assetDir, err = ioutil.TempDir("", "hypervtest-assets") 28 | Expect(err).NotTo(HaveOccurred()) 29 | 30 | downloadFile(filepath.Join(assetDir, "cfdev-efi-v2.iso"), testIsoUrl) 31 | downloadFile(filepath.Join(assetDir, "disk.vhdx"), testVHDUrl) 32 | }) 33 | 34 | var _ = AfterSuite(func() { 35 | os.RemoveAll(assetDir) 36 | }) 37 | 38 | func downloadFile(filepath string, url string) error { 39 | out, err := os.Create(filepath) 40 | if err != nil { 41 | return err 42 | } 43 | defer out.Close() 44 | 45 | resp, err := http.Get(url) 46 | if err != nil { 47 | return err 48 | } 49 | defer resp.Body.Close() 50 | 51 | _, err = io.Copy(out, resp.Body) 52 | if err != nil { 53 | return err 54 | } 55 | 56 | return nil 57 | } -------------------------------------------------------------------------------- /errors/errors_test.go: -------------------------------------------------------------------------------- 1 | package errors_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "code.cloudfoundry.org/cfdev/errors" 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | ) 10 | 11 | var _ = Describe("SafeWrap", func() { 12 | It("returns a wrapped error", func() { 13 | err := errors.SafeWrap(fmt.Errorf("other"), "safe text") 14 | Expect(err).To(MatchError("safe text: other")) 15 | }) 16 | 17 | Describe("SafeError", func() { 18 | It("returns ONLY the safe errors", func() { 19 | err := errors.SafeWrap(fmt.Errorf("other"), "safe text") 20 | Expect(errors.SafeError(err)).To(Equal("safe text")) 21 | }) 22 | 23 | It("returns ALL the safe errors", func() { 24 | err := errors.SafeWrap(fmt.Errorf("other"), "safe text") 25 | err = errors.SafeWrap(err, "outer text") 26 | Expect(errors.SafeError(err)).To(Equal("outer text: safe text")) 27 | }) 28 | 29 | It("returns empty string for non safe errors", func() { 30 | err := fmt.Errorf("other") 31 | Expect(errors.SafeError(err)).To(Equal("")) 32 | }) 33 | }) 34 | 35 | Context("causing error is nil", func() { 36 | It("uses just the message", func() { 37 | err := errors.SafeWrap(nil, "safe text") 38 | Expect(err.Error()).To(Equal("safe text")) 39 | Expect(errors.SafeError(err)).To(Equal("safe text")) 40 | }) 41 | }) 42 | }) 43 | -------------------------------------------------------------------------------- /cfanalytics/mocks/ui.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cfanalytics (interfaces: UI) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockUI is a mock of UI interface 13 | type MockUI struct { 14 | ctrl *gomock.Controller 15 | recorder *MockUIMockRecorder 16 | } 17 | 18 | // MockUIMockRecorder is the mock recorder for MockUI 19 | type MockUIMockRecorder struct { 20 | mock *MockUI 21 | } 22 | 23 | // NewMockUI creates a new mock instance 24 | func NewMockUI(ctrl *gomock.Controller) *MockUI { 25 | mock := &MockUI{ctrl: ctrl} 26 | mock.recorder = &MockUIMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockUI) EXPECT() *MockUIMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Ask mocks base method 36 | func (m *MockUI) Ask(arg0 string) string { 37 | ret := m.ctrl.Call(m, "Ask", arg0) 38 | ret0, _ := ret[0].(string) 39 | return ret0 40 | } 41 | 42 | // Ask indicates an expected call of Ask 43 | func (mr *MockUIMockRecorder) Ask(arg0 interface{}) *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ask", reflect.TypeOf((*MockUI)(nil).Ask), arg0) 45 | } 46 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/app_create.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | ) 9 | 10 | type AppCreate struct { 11 | CCClient CloudControllerClient 12 | AnalyticsClient *segment.Client 13 | Logger *log.Logger 14 | } 15 | 16 | var buildpackWhitelist = map[string]string{ 17 | "staticfile_buildpack": "staticfile", 18 | "java_buildpack": "java", 19 | "ruby_buildpack": "ruby", 20 | "dotnet_core_buildpack": "dotnet_core", 21 | "nodejs_buildpack": "nodejs", 22 | "go_buildpack": "go", 23 | "python_buildpack": "python", 24 | "php_buildpack": "php", 25 | "binary_buildpack": "binary", 26 | "": "unspecified", 27 | } 28 | 29 | func (c *AppCreate) HandleResponse(body json.RawMessage) error { 30 | var metadata struct { 31 | Request struct { 32 | Buildpack string 33 | } 34 | } 35 | 36 | json.Unmarshal(body, &metadata) 37 | 38 | buildpack, ok := buildpackWhitelist[metadata.Request.Buildpack] 39 | if !ok { 40 | buildpack = "custom" 41 | } 42 | 43 | err := c.AnalyticsClient.Enqueue("app created", map[string]string{ 44 | "buildpack": buildpack, 45 | }) 46 | 47 | if err != nil { 48 | return fmt.Errorf("failed to send analytics: %v", err) 49 | } 50 | 51 | return nil 52 | } 53 | -------------------------------------------------------------------------------- /cmd/start/mocks/cfdevd.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: CFDevD) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockCFDevD is a mock of CFDevD interface 13 | type MockCFDevD struct { 14 | ctrl *gomock.Controller 15 | recorder *MockCFDevDMockRecorder 16 | } 17 | 18 | // MockCFDevDMockRecorder is the mock recorder for MockCFDevD 19 | type MockCFDevDMockRecorder struct { 20 | mock *MockCFDevD 21 | } 22 | 23 | // NewMockCFDevD creates a new mock instance 24 | func NewMockCFDevD(ctrl *gomock.Controller) *MockCFDevD { 25 | mock := &MockCFDevD{ctrl: ctrl} 26 | mock.recorder = &MockCFDevDMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockCFDevD) EXPECT() *MockCFDevDMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Install mocks base method 36 | func (m *MockCFDevD) Install() error { 37 | ret := m.ctrl.Call(m, "Install") 38 | ret0, _ := ret[0].(error) 39 | return ret0 40 | } 41 | 42 | // Install indicates an expected call of Install 43 | func (mr *MockCFDevDMockRecorder) Install() *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Install", reflect.TypeOf((*MockCFDevD)(nil).Install)) 45 | } 46 | -------------------------------------------------------------------------------- /cmd/start/mocks/os.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: OS) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | os "code.cloudfoundry.org/cfdev/os" 9 | gomock "github.com/golang/mock/gomock" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockOS is a mock of OS interface 14 | type MockOS struct { 15 | ctrl *gomock.Controller 16 | recorder *MockOSMockRecorder 17 | } 18 | 19 | // MockOSMockRecorder is the mock recorder for MockOS 20 | type MockOSMockRecorder struct { 21 | mock *MockOS 22 | } 23 | 24 | // NewMockOS creates a new mock instance 25 | func NewMockOS(ctrl *gomock.Controller) *MockOS { 26 | mock := &MockOS{ctrl: ctrl} 27 | mock.recorder = &MockOSMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockOS) EXPECT() *MockOSMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Stats mocks base method 37 | func (m *MockOS) Stats() (os.Stats, error) { 38 | ret := m.ctrl.Call(m, "Stats") 39 | ret0, _ := ret[0].(os.Stats) 40 | ret1, _ := ret[1].(error) 41 | return ret0, ret1 42 | } 43 | 44 | // Stats indicates an expected call of Stats 45 | func (mr *MockOSMockRecorder) Stats() *gomock.Call { 46 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stats", reflect.TypeOf((*MockOS)(nil).Stats)) 47 | } 48 | -------------------------------------------------------------------------------- /daemon/servicew_linux.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | "code.cloudfoundry.org/cfdev/pkg/servicew/client" 6 | swconfig "code.cloudfoundry.org/cfdev/pkg/servicew/config" 7 | "path/filepath" 8 | ) 9 | 10 | type ServiceWrapper struct { 11 | swc *client.ServiceWrapper 12 | } 13 | 14 | func NewServiceWrapper(cfg config.Config) *ServiceWrapper { 15 | var ( 16 | binaryPath = filepath.Join(cfg.CacheDir, "servicew") 17 | workdir = cfg.DaemonDir 18 | swc = client.New(binaryPath, workdir) 19 | ) 20 | 21 | return &ServiceWrapper{ 22 | swc: swc, 23 | } 24 | } 25 | 26 | func (s *ServiceWrapper) AddDaemon(spec DaemonSpec) error { 27 | var ( 28 | definition = swconfig.Config{ 29 | Args: spec.ProgramArguments, 30 | Env: spec.EnvironmentVariables, 31 | Executable: spec.Program, 32 | Label: spec.Label, 33 | Log: spec.LogPath, 34 | Options: spec.Options, 35 | } 36 | ) 37 | 38 | return s.swc.Install(definition) 39 | } 40 | 41 | func (s *ServiceWrapper) RemoveDaemon(label string) error { 42 | return s.swc.Uninstall(label) 43 | } 44 | 45 | func (s *ServiceWrapper) Start(label string) error { 46 | return s.swc.Start(label) 47 | } 48 | 49 | func (s *ServiceWrapper) Stop(label string) error { 50 | return s.swc.Stop(label) 51 | } 52 | 53 | func (s *ServiceWrapper) IsRunning(label string) (bool, error) { 54 | return s.swc.IsRunning(label) 55 | } 56 | -------------------------------------------------------------------------------- /cmd/start/mocks/host.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: Host) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockHost is a mock of Host interface 13 | type MockHost struct { 14 | ctrl *gomock.Controller 15 | recorder *MockHostMockRecorder 16 | } 17 | 18 | // MockHostMockRecorder is the mock recorder for MockHost 19 | type MockHostMockRecorder struct { 20 | mock *MockHost 21 | } 22 | 23 | // NewMockHost creates a new mock instance 24 | func NewMockHost(ctrl *gomock.Controller) *MockHost { 25 | mock := &MockHost{ctrl: ctrl} 26 | mock.recorder = &MockHostMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockHost) EXPECT() *MockHostMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // CheckRequirements mocks base method 36 | func (m *MockHost) CheckRequirements() error { 37 | ret := m.ctrl.Call(m, "CheckRequirements") 38 | ret0, _ := ret[0].(error) 39 | return ret0 40 | } 41 | 42 | // CheckRequirements indicates an expected call of CheckRequirements 43 | func (mr *MockHostMockRecorder) CheckRequirements() *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckRequirements", reflect.TypeOf((*MockHost)(nil).CheckRequirements)) 45 | } 46 | -------------------------------------------------------------------------------- /cmd/stop/mocks/host.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/stop (interfaces: Host) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockHost is a mock of Host interface 13 | type MockHost struct { 14 | ctrl *gomock.Controller 15 | recorder *MockHostMockRecorder 16 | } 17 | 18 | // MockHostMockRecorder is the mock recorder for MockHost 19 | type MockHostMockRecorder struct { 20 | mock *MockHost 21 | } 22 | 23 | // NewMockHost creates a new mock instance 24 | func NewMockHost(ctrl *gomock.Controller) *MockHost { 25 | mock := &MockHost{ctrl: ctrl} 26 | mock.recorder = &MockHostMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockHost) EXPECT() *MockHostMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // CheckRequirements mocks base method 36 | func (m *MockHost) CheckRequirements() error { 37 | ret := m.ctrl.Call(m, "CheckRequirements") 38 | ret0, _ := ret[0].(error) 39 | return ret0 40 | } 41 | 42 | // CheckRequirements indicates an expected call of CheckRequirements 43 | func (mr *MockHostMockRecorder) CheckRequirements() *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CheckRequirements", reflect.TypeOf((*MockHost)(nil).CheckRequirements)) 45 | } 46 | -------------------------------------------------------------------------------- /cmd/version/version_suite_test.go: -------------------------------------------------------------------------------- 1 | package version_test 2 | 3 | import ( 4 | "archive/tar" 5 | "compress/gzip" 6 | "fmt" 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | "io" 10 | "os" 11 | "path/filepath" 12 | "strings" 13 | 14 | "testing" 15 | ) 16 | 17 | func TestVersion(t *testing.T) { 18 | RegisterFailHandler(Fail) 19 | RunSpecs(t, "Cmd Version Suite") 20 | } 21 | 22 | func tarArchive(src string, writers ...io.Writer) error { 23 | if _, err := os.Stat(src); err != nil { 24 | return fmt.Errorf("Unable to tar files - %v", err.Error()) 25 | } 26 | 27 | mw := io.MultiWriter(writers...) 28 | 29 | gzw := gzip.NewWriter(mw) 30 | defer gzw.Close() 31 | 32 | tw := tar.NewWriter(gzw) 33 | defer tw.Close() 34 | 35 | return filepath.Walk(src, func(file string, fi os.FileInfo, err error) error { 36 | 37 | if err != nil { 38 | return err 39 | } 40 | 41 | header, err := tar.FileInfoHeader(fi, fi.Name()) 42 | if err != nil { 43 | return err 44 | } 45 | 46 | header.Name = strings.TrimPrefix(strings.Replace(file, src, "", -1), string(filepath.Separator)) 47 | 48 | if err := tw.WriteHeader(header); err != nil { 49 | return err 50 | } 51 | 52 | if !fi.Mode().IsRegular() { 53 | return nil 54 | } 55 | 56 | f, err := os.Open(file) 57 | if err != nil { 58 | return err 59 | } 60 | 61 | if _, err := io.Copy(tw, f); err != nil { 62 | return err 63 | } 64 | 65 | f.Close() 66 | 67 | return nil 68 | }) 69 | } -------------------------------------------------------------------------------- /cmd/start/mocks/stop.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: Stop) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | cobra "github.com/spf13/cobra" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockStop is a mock of Stop interface 14 | type MockStop struct { 15 | ctrl *gomock.Controller 16 | recorder *MockStopMockRecorder 17 | } 18 | 19 | // MockStopMockRecorder is the mock recorder for MockStop 20 | type MockStopMockRecorder struct { 21 | mock *MockStop 22 | } 23 | 24 | // NewMockStop creates a new mock instance 25 | func NewMockStop(ctrl *gomock.Controller) *MockStop { 26 | mock := &MockStop{ctrl: ctrl} 27 | mock.recorder = &MockStopMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockStop) EXPECT() *MockStopMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // RunE mocks base method 37 | func (m *MockStop) RunE(arg0 *cobra.Command, arg1 []string) error { 38 | ret := m.ctrl.Call(m, "RunE", arg0, arg1) 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // RunE indicates an expected call of RunE 44 | func (mr *MockStopMockRecorder) RunE(arg0, arg1 interface{}) *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RunE", reflect.TypeOf((*MockStop)(nil).RunE), arg0, arg1) 46 | } 47 | -------------------------------------------------------------------------------- /cmd/start/mocks/cache.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: Cache) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | resource "code.cloudfoundry.org/cfdev/resource" 9 | gomock "github.com/golang/mock/gomock" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockCache is a mock of Cache interface 14 | type MockCache struct { 15 | ctrl *gomock.Controller 16 | recorder *MockCacheMockRecorder 17 | } 18 | 19 | // MockCacheMockRecorder is the mock recorder for MockCache 20 | type MockCacheMockRecorder struct { 21 | mock *MockCache 22 | } 23 | 24 | // NewMockCache creates a new mock instance 25 | func NewMockCache(ctrl *gomock.Controller) *MockCache { 26 | mock := &MockCache{ctrl: ctrl} 27 | mock.recorder = &MockCacheMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockCache) EXPECT() *MockCacheMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Sync mocks base method 37 | func (m *MockCache) Sync(arg0 resource.Catalog) error { 38 | ret := m.ctrl.Call(m, "Sync", arg0) 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // Sync indicates an expected call of Sync 44 | func (mr *MockCacheMockRecorder) Sync(arg0 interface{}) *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Sync", reflect.TypeOf((*MockCache)(nil).Sync), arg0) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/cfdevd/cmd/remove_ip_alias.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "net" 8 | "os" 9 | "os/exec" 10 | "strings" 11 | ) 12 | 13 | type RemoveIPAliasCommand struct { 14 | } 15 | 16 | const loopback = "lo0" 17 | 18 | func (u *RemoveIPAliasCommand) Execute(conn *net.UnixConn) error { 19 | err := u.RemoveLoopbackAliases(BOSH_IP, GOROUTER_IP) 20 | if err == nil { 21 | conn.Write([]byte{0}) 22 | } else { 23 | conn.Write([]byte{1}) 24 | } 25 | 26 | return err 27 | } 28 | 29 | func (u *RemoveIPAliasCommand) RemoveLoopbackAliases(addrs ...string) error { 30 | for _, addr := range addrs { 31 | if exists, err := aliasExists(addr); err != nil { 32 | return err 33 | } else if exists { 34 | if err := removeAlias(addr); err != nil { 35 | return fmt.Errorf("removing alias %s: %s", addr, err) 36 | } 37 | } 38 | } 39 | return nil 40 | } 41 | 42 | func aliasExists(alias string) (bool, error) { 43 | addrs, err := net.InterfaceAddrs() 44 | if err != nil { 45 | return false, fmt.Errorf("getting interface addrs: %s", err) 46 | } 47 | for _, addr := range addrs { 48 | if strings.Contains(addr.String(), alias) { 49 | return true, nil 50 | } 51 | } 52 | 53 | return false, nil 54 | } 55 | 56 | func removeAlias(alias string) error { 57 | cmd := exec.Command("sudo", "-S", "ifconfig", loopback, "inet", alias+"/32", "remove") 58 | cmd.Stdout = os.Stdout 59 | cmd.Stderr = os.Stderr 60 | cmd.Stdin = os.Stdin 61 | 62 | return cmd.Run() 63 | } 64 | -------------------------------------------------------------------------------- /config/proxy.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "os" 5 | "strings" 6 | ) 7 | 8 | type ProxyConfig struct { 9 | Http string `json:"http,omitempty"` 10 | Https string `json:"https,omitempty"` 11 | NoProxy string `json:"exclude,omitempty"` 12 | } 13 | 14 | func (c *Config) BuildProxyConfig() ProxyConfig { 15 | httpProxy := os.Getenv("http_proxy") 16 | if os.Getenv("HTTP_PROXY") != "" { 17 | httpProxy = os.Getenv("HTTP_PROXY") 18 | } 19 | 20 | httpsProxy := os.Getenv("https_proxy") 21 | if os.Getenv("HTTPS_PROXY") != "" { 22 | httpsProxy = os.Getenv("HTTPS_PROXY") 23 | } 24 | 25 | noProxy := os.Getenv("no_proxy") 26 | if os.Getenv("NO_PROXY") != "" { 27 | noProxy = os.Getenv("NO_PROXY") 28 | } 29 | 30 | if c.BoshDirectorIP != "" && !strings.Contains(noProxy, c.BoshDirectorIP) { 31 | noProxy = strings.Join([]string{noProxy, c.BoshDirectorIP}, ",") 32 | } 33 | 34 | if c.CFRouterIP != "" && !strings.Contains(noProxy, c.CFRouterIP) { 35 | noProxy = strings.Join([]string{noProxy, c.CFRouterIP}, ",") 36 | } 37 | 38 | if c.HostIP != "" && !strings.Contains(noProxy, c.HostIP) { 39 | noProxy = strings.Join([]string{noProxy, c.HostIP}, ",") 40 | } 41 | 42 | return ProxyConfig{ 43 | Http: httpProxy, 44 | Https: httpsProxy, 45 | NoProxy: noProxy, 46 | } 47 | } 48 | 49 | func IsBehindProxy() bool { 50 | return os.Getenv("HTTP_PROXY") != "" || 51 | os.Getenv("http_proxy") != "" || 52 | os.Getenv("HTTPS_PROXY") != "" || 53 | os.Getenv("https_proxy") != "" 54 | } 55 | -------------------------------------------------------------------------------- /cmd/bosh/mocks/ui.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/bosh (interfaces: UI) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockUI is a mock of UI interface 13 | type MockUI struct { 14 | ctrl *gomock.Controller 15 | recorder *MockUIMockRecorder 16 | } 17 | 18 | // MockUIMockRecorder is the mock recorder for MockUI 19 | type MockUIMockRecorder struct { 20 | mock *MockUI 21 | } 22 | 23 | // NewMockUI creates a new mock instance 24 | func NewMockUI(ctrl *gomock.Controller) *MockUI { 25 | mock := &MockUI{ctrl: ctrl} 26 | mock.recorder = &MockUIMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockUI) EXPECT() *MockUIMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Say mocks base method 36 | func (m *MockUI) Say(arg0 string, arg1 ...interface{}) { 37 | varargs := []interface{}{arg0} 38 | for _, a := range arg1 { 39 | varargs = append(varargs, a) 40 | } 41 | m.ctrl.Call(m, "Say", varargs...) 42 | } 43 | 44 | // Say indicates an expected call of Say 45 | func (mr *MockUIMockRecorder) Say(arg0 interface{}, arg1 ...interface{}) *gomock.Call { 46 | varargs := append([]interface{}{arg0}, arg1...) 47 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Say", reflect.TypeOf((*MockUI)(nil).Say), varargs...) 48 | } 49 | -------------------------------------------------------------------------------- /driver/hyperv/mocks/runner.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/driver/hyperv (interfaces: Runner) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockRunner is a mock of Runner interface 13 | type MockRunner struct { 14 | ctrl *gomock.Controller 15 | recorder *MockRunnerMockRecorder 16 | } 17 | 18 | // MockRunnerMockRecorder is the mock recorder for MockRunner 19 | type MockRunnerMockRecorder struct { 20 | mock *MockRunner 21 | } 22 | 23 | // NewMockRunner creates a new mock instance 24 | func NewMockRunner(ctrl *gomock.Controller) *MockRunner { 25 | mock := &MockRunner{ctrl: ctrl} 26 | mock.recorder = &MockRunnerMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockRunner) EXPECT() *MockRunnerMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Output mocks base method 36 | func (m *MockRunner) Output(arg0 string) (string, error) { 37 | ret := m.ctrl.Call(m, "Output", arg0) 38 | ret0, _ := ret[0].(string) 39 | ret1, _ := ret[1].(error) 40 | return ret0, ret1 41 | } 42 | 43 | // Output indicates an expected call of Output 44 | func (mr *MockRunnerMockRecorder) Output(arg0 interface{}) *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Output", reflect.TypeOf((*MockRunner)(nil).Output), arg0) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/analyticsd/segment/client.go: -------------------------------------------------------------------------------- 1 | package segment 2 | 3 | import ( 4 | "gopkg.in/segmentio/analytics-go.v3" 5 | "os" 6 | "runtime" 7 | "time" 8 | ) 9 | 10 | //go:generate mockgen -package mocks -destination mocks/analytics.go gopkg.in/segmentio/analytics-go.v3 Client 11 | 12 | type Client struct { 13 | analyticsClient analytics.Client 14 | uuid string 15 | version string 16 | osVersion string 17 | timeStamp time.Time 18 | } 19 | 20 | func New(analyticsClient analytics.Client, uuid string, version string, osVersion string, timeStamp time.Time) *Client { 21 | return &Client{ 22 | analyticsClient: analyticsClient, 23 | version: version, 24 | osVersion: osVersion, 25 | uuid: uuid, 26 | timeStamp: timeStamp, 27 | } 28 | } 29 | 30 | func (c *Client) Enqueue(event string, properties map[string]string) error { 31 | isBehindProxy := func() bool { 32 | return os.Getenv("HTTP_PROXY") != "" || 33 | os.Getenv("HTTPS_PROXY") != "" || 34 | os.Getenv("http_proxy") != "" || 35 | os.Getenv("https_proxy") != "" 36 | } 37 | 38 | p := analytics.NewProperties() 39 | p.Set("os", runtime.GOOS) 40 | p.Set("plugin_version", c.version) 41 | p.Set("os_version", c.osVersion) 42 | p.Set("proxy", isBehindProxy()) 43 | 44 | for k, v := range properties { 45 | p.Set(k, v) 46 | } 47 | 48 | return c.analyticsClient.Enqueue(analytics.Track{ 49 | UserId: c.uuid, 50 | Event: event, 51 | Timestamp: c.timeStamp, 52 | Properties: p, 53 | }) 54 | } 55 | -------------------------------------------------------------------------------- /pkg/cfdevd/cmd/mocks/launchd.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdevd/cmd (interfaces: Launchd) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | reflect "reflect" 9 | 10 | gomock "github.com/golang/mock/gomock" 11 | ) 12 | 13 | // MockLaunchd is a mock of Launchd interface 14 | type MockLaunchd struct { 15 | ctrl *gomock.Controller 16 | recorder *MockLaunchdMockRecorder 17 | } 18 | 19 | // MockLaunchdMockRecorder is the mock recorder for MockLaunchd 20 | type MockLaunchdMockRecorder struct { 21 | mock *MockLaunchd 22 | } 23 | 24 | // NewMockLaunchd creates a new mock instance 25 | func NewMockLaunchd(ctrl *gomock.Controller) *MockLaunchd { 26 | mock := &MockLaunchd{ctrl: ctrl} 27 | mock.recorder = &MockLaunchdMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockLaunchd) EXPECT() *MockLaunchdMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // RemoveDaemon mocks base method 37 | func (m *MockLaunchd) RemoveDaemon(arg0 string) error { 38 | ret := m.ctrl.Call(m, "RemoveDaemon", arg0) 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // RemoveDaemon indicates an expected call of RemoveDaemon 44 | func (mr *MockLaunchdMockRecorder) RemoveDaemon(arg0 interface{}) *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDaemon", reflect.TypeOf((*MockLaunchd)(nil).RemoveDaemon), arg0) 46 | } 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Everyone is encouraged to help improve this project. 4 | 5 | Please submit pull requests against the **master branch**. 6 | 7 | Here are some ways *you* can contribute: 8 | 9 | * by using nightly builds and prerelease versions 10 | * by reporting bugs 11 | * by suggesting new features 12 | * by writing or editing documentation 13 | * by writing specifications 14 | * by writing code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace) 15 | * by refactoring code 16 | * by closing [issues](https://github.com/pivotal-cf/cfdev/issues) 17 | * by reviewing patches 18 | 19 | ## Submitting an Issue 20 | 21 | We use the [GitHub issue tracker](https://github.com/pivotal-cf/cfdev/issues) to track bugs and features. 22 | Before submitting a bug report or feature request, check to make sure it hasn't already been submitted. 23 | You can indicate support for an existing issue by voting it up. 24 | When submitting a bug report, please include a [Gist](http://gist.github.com/) that includes a stack trace and any 25 | details that may be necessary to reproduce the bug including the CF Dev version. 26 | 27 | ## Submitting a Pull Request 28 | 29 | 1. Propose a change by opening an issue. 30 | 2. Fork the project. 31 | 3. Create a topic branch. 32 | 4. Implement your feature or bug fix. 33 | 5. Commit and push your changes. 34 | 6. Submit a pull request. 35 | 36 | ## Copyright 37 | 38 | See [LICENSE](LICENSE) for details. 39 | Copyright (c) 2018 [Pivotal Software, Inc](http://www.pivotal.io/). 40 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/service_create.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | ) 9 | 10 | type ServiceCreate struct { 11 | CCClient CloudControllerClient 12 | AnalyticsClient *segment.Client 13 | Logger *log.Logger 14 | } 15 | 16 | func (c *ServiceCreate) HandleResponse(body json.RawMessage) error { 17 | var metadata struct { 18 | Request struct { 19 | ServicePlanGuid string `json:"service_plan_guid"` 20 | } 21 | } 22 | 23 | json.Unmarshal(body, &metadata) 24 | 25 | var urlResp struct { 26 | Entity struct { 27 | ServiceURL string `json:"service_url"` 28 | } 29 | } 30 | 31 | path := "/v2/service_plans/" + metadata.Request.ServicePlanGuid 32 | err := c.CCClient.Fetch(path, nil, &urlResp) 33 | if err != nil { 34 | return fmt.Errorf("failed to make request to: %s: %s", path, err) 35 | } 36 | 37 | var labelResp struct { 38 | Entity struct { 39 | Label string 40 | } 41 | } 42 | 43 | path = urlResp.Entity.ServiceURL 44 | err = c.CCClient.Fetch(path, nil, &labelResp) 45 | if err != nil { 46 | return fmt.Errorf("failed to make request to: %s: %s", path, err) 47 | } 48 | 49 | if !serviceIsWhiteListed(labelResp.Entity.Label) { 50 | return nil 51 | } 52 | 53 | err = c.AnalyticsClient.Enqueue("created service", map[string]string{ 54 | "service": labelResp.Entity.Label, 55 | }) 56 | 57 | if err != nil { 58 | return fmt.Errorf("failed to send analytics: %v", err) 59 | } 60 | 61 | return nil 62 | } 63 | -------------------------------------------------------------------------------- /cmd/start/mocks/provisioner.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: Provisioner) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | time "time" 11 | ) 12 | 13 | // MockProvisioner is a mock of Provisioner interface 14 | type MockProvisioner struct { 15 | ctrl *gomock.Controller 16 | recorder *MockProvisionerMockRecorder 17 | } 18 | 19 | // MockProvisionerMockRecorder is the mock recorder for MockProvisioner 20 | type MockProvisionerMockRecorder struct { 21 | mock *MockProvisioner 22 | } 23 | 24 | // NewMockProvisioner creates a new mock instance 25 | func NewMockProvisioner(ctrl *gomock.Controller) *MockProvisioner { 26 | mock := &MockProvisioner{ctrl: ctrl} 27 | mock.recorder = &MockProvisionerMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockProvisioner) EXPECT() *MockProvisionerMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Ping mocks base method 37 | func (m *MockProvisioner) Ping(arg0 time.Duration) error { 38 | ret := m.ctrl.Call(m, "Ping", arg0) 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // Ping indicates an expected call of Ping 44 | func (mr *MockProvisionerMockRecorder) Ping(arg0 interface{}) *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Ping", reflect.TypeOf((*MockProvisioner)(nil).Ping), arg0) 46 | } 47 | -------------------------------------------------------------------------------- /scripts/generate-plugin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -exo pipefail 3 | 4 | dir="$( cd "$( dirname "$0" )" && pwd )" 5 | home_dir=${CFDEV_HOME:-$HOME/.cfdev} 6 | cache_dir="$home_dir/cache" 7 | analyticskey="WFz4dVFXZUxN2Y6MzfUHJNWtlgXuOYV2" 8 | 9 | export GOOS=darwin 10 | export GOARCH=amd64 11 | 12 | cfdevd="$PWD"/cfdvd 13 | go build -o $cfdevd code.cloudfoundry.org/cfdev/pkg/cfdevd 14 | 15 | analyticsd="$PWD"/analytix 16 | analyticsdpkg="main" 17 | go build \ 18 | -o $analyticsd \ 19 | -ldflags \ 20 | "-X $analyticsdpkg.testAnalyticsKey=$analyticskey 21 | -X $analyticsdpkg.version=0.0.$(date +%Y%m%d-%H%M%S)" \ 22 | code.cloudfoundry.org/cfdev/pkg/analyticsd 23 | 24 | cfdepsUrl="$cache_dir/cfdev-deps.tgz" 25 | pkg="code.cloudfoundry.org/cfdev/config" 26 | 27 | go build \ 28 | -ldflags \ 29 | "-X $pkg.cfdepsUrl=file://$cfdepsUrl 30 | -X $pkg.cfdepsMd5=$(md5 $cfdepsUrl | awk '{ print $4 }') 31 | -X $pkg.cfdepsSize=$(wc -c < $cfdepsUrl | tr -d '[:space:]') 32 | 33 | -X $pkg.cfdevdUrl=file://$cfdevd 34 | -X $pkg.cfdevdMd5=$(md5 "$cfdevd" | awk '{ print $4 }') 35 | -X $pkg.cfdevdSize=$(wc -c < "$cfdevd" | tr -d '[:space:]') 36 | 37 | -X $pkg.analyticsdUrl=file://$analyticsd 38 | -X $pkg.analyticsdMd5=$(md5 "$analyticsd" | awk '{ print $4 }') 39 | -X $pkg.analyticsdSize=$(wc -c < "$analyticsd" | tr -d '[:space:]') 40 | 41 | -X $pkg.cliVersion=0.0.$(date +%Y%m%d-%H%M%S) 42 | -X $pkg.buildVersion=dev 43 | -X $pkg.testAnalyticsKey=$analyticskey" \ 44 | code.cloudfoundry.org/cfdev 45 | 46 | 47 | -------------------------------------------------------------------------------- /cmd/start/mocks/provision.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: Provision) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | start "code.cloudfoundry.org/cfdev/cmd/start" 9 | gomock "github.com/golang/mock/gomock" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockProvision is a mock of Provision interface 14 | type MockProvision struct { 15 | ctrl *gomock.Controller 16 | recorder *MockProvisionMockRecorder 17 | } 18 | 19 | // MockProvisionMockRecorder is the mock recorder for MockProvision 20 | type MockProvisionMockRecorder struct { 21 | mock *MockProvision 22 | } 23 | 24 | // NewMockProvision creates a new mock instance 25 | func NewMockProvision(ctrl *gomock.Controller) *MockProvision { 26 | mock := &MockProvision{ctrl: ctrl} 27 | mock.recorder = &MockProvisionMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockProvision) EXPECT() *MockProvisionMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Execute mocks base method 37 | func (m *MockProvision) Execute(arg0 start.Args) error { 38 | ret := m.ctrl.Call(m, "Execute", arg0) 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // Execute indicates an expected call of Execute 44 | func (mr *MockProvisionMockRecorder) Execute(arg0 interface{}) *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Execute", reflect.TypeOf((*MockProvision)(nil).Execute), arg0) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/servicew/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/servicew/config" 5 | "code.cloudfoundry.org/cfdev/pkg/servicew/program" 6 | "fmt" 7 | "gopkg.in/yaml.v2" 8 | "io/ioutil" 9 | "log" 10 | "os" 11 | "path/filepath" 12 | ) 13 | 14 | func main() { 15 | configPath, err := configPath() 16 | expectNoError(err) 17 | 18 | contents, err := ioutil.ReadFile(configPath) 19 | expectNoError(err) 20 | 21 | var conf config.Config 22 | err = yaml.Unmarshal(contents, &conf) 23 | expectNoError(err) 24 | 25 | prog, err := program.New(conf) 26 | expectNoError(err) 27 | 28 | if len(os.Args) == 1 { 29 | err = prog.Service.Run() 30 | expectNoError(err) 31 | 32 | os.Exit(0) 33 | } 34 | 35 | switch os.Args[1] { 36 | case "status": 37 | fmt.Println(prog.Status()) 38 | case "install": 39 | err = prog.Install() 40 | case "start": 41 | err = prog.StartService() 42 | case "stop": 43 | err = prog.StopService() 44 | case "uninstall": 45 | err = prog.Uninstall() 46 | default: 47 | err = fmt.Errorf("unsupported command: '%q'", os.Args[1]) 48 | } 49 | 50 | expectNoError(err) 51 | } 52 | 53 | func configPath() (string, error) { 54 | fullexecpath, err := os.Executable() 55 | if err != nil { 56 | return "", err 57 | } 58 | 59 | dir, execname := filepath.Split(fullexecpath) 60 | ext := filepath.Ext(execname) 61 | name := execname[:len(execname)-len(ext)] 62 | 63 | return filepath.Join(dir, name+".yml"), nil 64 | } 65 | 66 | func expectNoError(err error) { 67 | if err != nil { 68 | log.Fatalln("Error:", err) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /cmd/stop/mocks/process_manager.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/stop (interfaces: ProcManager) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockProcManager is a mock of ProcManager interface 13 | type MockProcManager struct { 14 | ctrl *gomock.Controller 15 | recorder *MockProcManagerMockRecorder 16 | } 17 | 18 | // MockProcManagerMockRecorder is the mock recorder for MockProcManager 19 | type MockProcManagerMockRecorder struct { 20 | mock *MockProcManager 21 | } 22 | 23 | // NewMockProcManager creates a new mock instance 24 | func NewMockProcManager(ctrl *gomock.Controller) *MockProcManager { 25 | mock := &MockProcManager{ctrl: ctrl} 26 | mock.recorder = &MockProcManagerMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockProcManager) EXPECT() *MockProcManagerMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // SafeKill mocks base method 36 | func (m *MockProcManager) SafeKill(arg0, arg1 string) error { 37 | ret := m.ctrl.Call(m, "SafeKill", arg0, arg1) 38 | ret0, _ := ret[0].(error) 39 | return ret0 40 | } 41 | 42 | // SafeKill indicates an expected call of SafeKill 43 | func (mr *MockProcManagerMockRecorder) SafeKill(arg0, arg1 interface{}) *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SafeKill", reflect.TypeOf((*MockProcManager)(nil).SafeKill), arg0, arg1) 45 | } 46 | -------------------------------------------------------------------------------- /pkg/cfdevd/cmd/mocks/daemonrunner.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdevd/cmd (interfaces: DaemonRunner) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockDaemonRunner is a mock of DaemonRunner interface 13 | type MockDaemonRunner struct { 14 | ctrl *gomock.Controller 15 | recorder *MockDaemonRunnerMockRecorder 16 | } 17 | 18 | // MockDaemonRunnerMockRecorder is the mock recorder for MockDaemonRunner 19 | type MockDaemonRunnerMockRecorder struct { 20 | mock *MockDaemonRunner 21 | } 22 | 23 | // NewMockDaemonRunner creates a new mock instance 24 | func NewMockDaemonRunner(ctrl *gomock.Controller) *MockDaemonRunner { 25 | mock := &MockDaemonRunner{ctrl: ctrl} 26 | mock.recorder = &MockDaemonRunnerMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockDaemonRunner) EXPECT() *MockDaemonRunnerMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // RemoveDaemon mocks base method 36 | func (m *MockDaemonRunner) RemoveDaemon(arg0 string) error { 37 | ret := m.ctrl.Call(m, "RemoveDaemon", arg0) 38 | ret0, _ := ret[0].(error) 39 | return ret0 40 | } 41 | 42 | // RemoveDaemon indicates an expected call of RemoveDaemon 43 | func (mr *MockDaemonRunnerMockRecorder) RemoveDaemon(arg0 interface{}) *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDaemon", reflect.TypeOf((*MockDaemonRunner)(nil).RemoveDaemon), arg0) 45 | } 46 | -------------------------------------------------------------------------------- /cmd/stop/stop.go: -------------------------------------------------------------------------------- 1 | package stop 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/cfanalytics" 5 | "code.cloudfoundry.org/cfdev/driver" 6 | "code.cloudfoundry.org/cfdev/errors" 7 | "github.com/spf13/cobra" 8 | ) 9 | 10 | //go:generate mockgen -package mocks -destination mocks/analytics.go code.cloudfoundry.org/cfdev/cmd/stop Analytics 11 | type Analytics interface { 12 | Event(event string, data ...map[string]interface{}) error 13 | } 14 | 15 | //go:generate mockgen -package mocks -destination mocks/analyticsd.go code.cloudfoundry.org/cfdev/cmd/stop AnalyticsD 16 | type AnalyticsD interface { 17 | Stop() error 18 | Destroy() error 19 | } 20 | 21 | type Stop struct { 22 | Driver driver.Driver 23 | Analytics Analytics 24 | AnalyticsD AnalyticsD 25 | } 26 | 27 | func (s *Stop) Cmd() *cobra.Command { 28 | return &cobra.Command{ 29 | Use: "stop", 30 | RunE: s.RunE, 31 | } 32 | } 33 | 34 | func (s *Stop) RunE(cmd *cobra.Command, args []string) error { 35 | s.Analytics.Event(cfanalytics.STOP) 36 | 37 | if err := s.Driver.CheckRequirements(); err != nil { 38 | return err 39 | } 40 | 41 | var reterr error 42 | 43 | if err := s.AnalyticsD.Stop(); err != nil { 44 | reterr = errors.SafeWrap(err, "failed to stop analyticsd") 45 | } 46 | 47 | if err := s.AnalyticsD.Destroy(); err != nil { 48 | reterr = errors.SafeWrap(err, "failed to destroy analyticsd") 49 | } 50 | 51 | if err := s.Driver.Stop(); err != nil { 52 | reterr = errors.SafeWrap(err, "failed to stop the VM") 53 | } 54 | 55 | if reterr != nil { 56 | return errors.SafeWrap(reterr, "cf dev stop") 57 | } 58 | 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /resource/progress/progress.go: -------------------------------------------------------------------------------- 1 | package progress 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "strings" 7 | ) 8 | 9 | type Progress struct { 10 | current uint64 11 | currentLastCompleted uint64 12 | total uint64 13 | lastPercentage int 14 | writer io.Writer 15 | } 16 | 17 | func New(writer io.Writer) *Progress { 18 | return &Progress{writer: writer} 19 | } 20 | 21 | func (c *Progress) Start(total uint64) { 22 | c.lastPercentage = -1 23 | c.current = 0 24 | c.total = total 25 | fmt.Fprintf(c.writer, "\rProgress: |%-21s| 0%%", ">") 26 | } 27 | 28 | func (c *Progress) Write(p []byte) (int, error) { 29 | c.current += uint64(len(p)) 30 | c.display() 31 | return len(p), nil 32 | } 33 | 34 | func (c *Progress) Add(add uint64) { 35 | c.current += add 36 | c.display() 37 | } 38 | 39 | func (c *Progress) SetLastCompleted() { 40 | c.currentLastCompleted = c.current 41 | } 42 | 43 | func (c *Progress) ResetCurrent() { 44 | c.current = c.currentLastCompleted 45 | c.lastPercentage = c.lastPercentage + 1 //increment in order to print during retries 46 | } 47 | 48 | func (c *Progress) End() { 49 | fmt.Fprintf(c.writer, "\r\n") 50 | } 51 | 52 | func (c *Progress) display() { 53 | if c.total == 0 { 54 | fmt.Fprintf(c.writer, "\rProgress: %d bytes", c.current) 55 | return 56 | } 57 | percentage := int(c.current * 1000 / c.total) 58 | if c.lastPercentage == percentage { 59 | return 60 | } 61 | c.lastPercentage = percentage 62 | 63 | fmt.Fprintf(c.writer, 64 | "\rProgress: |%-21s| %.1f%%", 65 | strings.Repeat("=", percentage/50)+">", 66 | float64(percentage)/10.0) 67 | } 68 | -------------------------------------------------------------------------------- /cmd/download/download.go: -------------------------------------------------------------------------------- 1 | package download 2 | 3 | import ( 4 | "io" 5 | "os" 6 | "time" 7 | 8 | "net/http" 9 | 10 | "code.cloudfoundry.org/cfdev/config" 11 | "code.cloudfoundry.org/cfdev/errors" 12 | "code.cloudfoundry.org/cfdev/resource" 13 | "code.cloudfoundry.org/cfdev/resource/progress" 14 | "github.com/spf13/cobra" 15 | ) 16 | 17 | type UI interface { 18 | Say(message string, args ...interface{}) 19 | Writer() io.Writer 20 | } 21 | 22 | type Workspace interface { 23 | CreateDirs() error 24 | } 25 | 26 | type Download struct { 27 | Exit chan struct{} 28 | UI UI 29 | Config config.Config 30 | Workspace Workspace 31 | } 32 | 33 | func (d *Download) Cmd() *cobra.Command { 34 | return &cobra.Command{ 35 | Use: "download", 36 | RunE: d.RunE, 37 | } 38 | } 39 | 40 | func (d *Download) RunE(cmd *cobra.Command, args []string) error { 41 | go func() { 42 | <-d.Exit 43 | os.Exit(128) 44 | }() 45 | 46 | if err := d.Workspace.CreateDirs(); err != nil { 47 | return errors.SafeWrap(err, "setup for download") 48 | } 49 | 50 | d.UI.Say("Downloading Resources...") 51 | return CacheSync(d.Config.Dependencies, d.Config.CacheDir, d.UI.Writer()) 52 | } 53 | 54 | func CacheSync(dependencies resource.Catalog, cacheDir string, writer io.Writer) error { 55 | cache := resource.Cache{ 56 | Dir: cacheDir, 57 | HttpDo: http.DefaultClient.Do, 58 | Progress: progress.New(writer), 59 | RetryWait: time.Second, 60 | Writer: writer, 61 | } 62 | 63 | if err := cache.Sync(dependencies); err != nil { 64 | return errors.SafeWrap(err, "Unable to sync assets") 65 | } 66 | 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /cmd/start/mocks/network.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: HostNet) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockHostNet is a mock of HostNet interface 13 | type MockHostNet struct { 14 | ctrl *gomock.Controller 15 | recorder *MockHostNetMockRecorder 16 | } 17 | 18 | // MockHostNetMockRecorder is the mock recorder for MockHostNet 19 | type MockHostNetMockRecorder struct { 20 | mock *MockHostNet 21 | } 22 | 23 | // NewMockHostNet creates a new mock instance 24 | func NewMockHostNet(ctrl *gomock.Controller) *MockHostNet { 25 | mock := &MockHostNet{ctrl: ctrl} 26 | mock.recorder = &MockHostNetMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockHostNet) EXPECT() *MockHostNetMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // AddLoopbackAliases mocks base method 36 | func (m *MockHostNet) AddLoopbackAliases(arg0 ...string) error { 37 | varargs := []interface{}{} 38 | for _, a := range arg0 { 39 | varargs = append(varargs, a) 40 | } 41 | ret := m.ctrl.Call(m, "AddLoopbackAliases", varargs...) 42 | ret0, _ := ret[0].(error) 43 | return ret0 44 | } 45 | 46 | // AddLoopbackAliases indicates an expected call of AddLoopbackAliases 47 | func (mr *MockHostNetMockRecorder) AddLoopbackAliases(arg0 ...interface{}) *gomock.Call { 48 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddLoopbackAliases", reflect.TypeOf((*MockHostNet)(nil).AddLoopbackAliases), arg0...) 49 | } 50 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/service_bind.go: -------------------------------------------------------------------------------- 1 | package command 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 5 | "encoding/json" 6 | "fmt" 7 | "log" 8 | ) 9 | 10 | type ServiceBind struct { 11 | CCClient CloudControllerClient 12 | AnalyticsClient *segment.Client 13 | Logger *log.Logger 14 | } 15 | 16 | func (c *ServiceBind) HandleResponse(body json.RawMessage) error { 17 | var metadata struct { 18 | Request struct { 19 | Relationships struct { 20 | ServiceInstance struct { 21 | Data struct { 22 | Guid string 23 | } 24 | } `json:"service_instance"` 25 | } 26 | } 27 | } 28 | 29 | json.Unmarshal(body, &metadata) 30 | 31 | var urlResp struct { 32 | Entity struct { 33 | ServiceURL string `json:"service_url"` 34 | } 35 | } 36 | 37 | path := "/v2/service_instances/" + metadata.Request.Relationships.ServiceInstance.Data.Guid 38 | err := c.CCClient.Fetch(path, nil, &urlResp) 39 | if err != nil { 40 | return fmt.Errorf("failed to make request to: %s: %s", path, err) 41 | } 42 | 43 | var labelResp struct { 44 | Entity struct { 45 | Label string 46 | } 47 | } 48 | 49 | path = urlResp.Entity.ServiceURL 50 | err = c.CCClient.Fetch(path, nil, &labelResp) 51 | if err != nil { 52 | return fmt.Errorf("failed to make request to: %s: %s", path, err) 53 | } 54 | 55 | if !serviceIsWhiteListed(labelResp.Entity.Label) { 56 | return nil 57 | } 58 | 59 | err = c.AnalyticsClient.Enqueue("app bound to service", map[string]string{ 60 | "service": labelResp.Entity.Label, 61 | }) 62 | 63 | if err != nil { 64 | return fmt.Errorf("failed to send analytics: %v", err) 65 | } 66 | 67 | return nil 68 | } 69 | -------------------------------------------------------------------------------- /provision/mocks/runner.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/provision (interfaces: BoshRunner) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockBoshRunner is a mock of BoshRunner interface 13 | type MockBoshRunner struct { 14 | ctrl *gomock.Controller 15 | recorder *MockBoshRunnerMockRecorder 16 | } 17 | 18 | // MockBoshRunnerMockRecorder is the mock recorder for MockBoshRunner 19 | type MockBoshRunnerMockRecorder struct { 20 | mock *MockBoshRunner 21 | } 22 | 23 | // NewMockBoshRunner creates a new mock instance 24 | func NewMockBoshRunner(ctrl *gomock.Controller) *MockBoshRunner { 25 | mock := &MockBoshRunner{ctrl: ctrl} 26 | mock.recorder = &MockBoshRunnerMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockBoshRunner) EXPECT() *MockBoshRunnerMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Output mocks base method 36 | func (m *MockBoshRunner) Output(arg0 ...string) ([]byte, error) { 37 | varargs := []interface{}{} 38 | for _, a := range arg0 { 39 | varargs = append(varargs, a) 40 | } 41 | ret := m.ctrl.Call(m, "Output", varargs...) 42 | ret0, _ := ret[0].([]byte) 43 | ret1, _ := ret[1].(error) 44 | return ret0, ret1 45 | } 46 | 47 | // Output indicates an expected call of Output 48 | func (mr *MockBoshRunnerMockRecorder) Output(arg0 ...interface{}) *gomock.Call { 49 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Output", reflect.TypeOf((*MockBoshRunner)(nil).Output), arg0...) 50 | } 51 | -------------------------------------------------------------------------------- /cmd/start/mocks/isoreader.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: MetaDataReader) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | workspace "code.cloudfoundry.org/cfdev/workspace" 9 | gomock "github.com/golang/mock/gomock" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockMetaDataReader is a mock of MetaDataReader interface 14 | type MockMetaDataReader struct { 15 | ctrl *gomock.Controller 16 | recorder *MockMetaDataReaderMockRecorder 17 | } 18 | 19 | // MockMetaDataReaderMockRecorder is the mock recorder for MockMetaDataReader 20 | type MockMetaDataReaderMockRecorder struct { 21 | mock *MockMetaDataReader 22 | } 23 | 24 | // NewMockMetaDataReader creates a new mock instance 25 | func NewMockMetaDataReader(ctrl *gomock.Controller) *MockMetaDataReader { 26 | mock := &MockMetaDataReader{ctrl: ctrl} 27 | mock.recorder = &MockMetaDataReaderMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockMetaDataReader) EXPECT() *MockMetaDataReaderMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Metadata mocks base method 37 | func (m *MockMetaDataReader) Metadata() (workspace.Metadata, error) { 38 | ret := m.ctrl.Call(m, "Metadata") 39 | ret0, _ := ret[0].(workspace.Metadata) 40 | ret1, _ := ret[1].(error) 41 | return ret0, ret1 42 | } 43 | 44 | // Metadata indicates an expected call of Metadata 45 | func (mr *MockMetaDataReaderMockRecorder) Metadata() *gomock.Call { 46 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Metadata", reflect.TypeOf((*MockMetaDataReader)(nil).Metadata)) 47 | } 48 | -------------------------------------------------------------------------------- /cmd/stop/mocks/network.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/stop (interfaces: HostNet) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockHostNet is a mock of HostNet interface 13 | type MockHostNet struct { 14 | ctrl *gomock.Controller 15 | recorder *MockHostNetMockRecorder 16 | } 17 | 18 | // MockHostNetMockRecorder is the mock recorder for MockHostNet 19 | type MockHostNetMockRecorder struct { 20 | mock *MockHostNet 21 | } 22 | 23 | // NewMockHostNet creates a new mock instance 24 | func NewMockHostNet(ctrl *gomock.Controller) *MockHostNet { 25 | mock := &MockHostNet{ctrl: ctrl} 26 | mock.recorder = &MockHostNetMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockHostNet) EXPECT() *MockHostNetMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // RemoveLoopbackAliases mocks base method 36 | func (m *MockHostNet) RemoveLoopbackAliases(arg0 ...string) error { 37 | varargs := []interface{}{} 38 | for _, a := range arg0 { 39 | varargs = append(varargs, a) 40 | } 41 | ret := m.ctrl.Call(m, "RemoveLoopbackAliases", varargs...) 42 | ret0, _ := ret[0].(error) 43 | return ret0 44 | } 45 | 46 | // RemoveLoopbackAliases indicates an expected call of RemoveLoopbackAliases 47 | func (mr *MockHostNetMockRecorder) RemoveLoopbackAliases(arg0 ...interface{}) *gomock.Call { 48 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveLoopbackAliases", reflect.TypeOf((*MockHostNet)(nil).RemoveLoopbackAliases), arg0...) 49 | } 50 | -------------------------------------------------------------------------------- /cmd/version/mocks/metadata.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: MetaDataReader) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | workspace "code.cloudfoundry.org/cfdev/workspace" 9 | gomock "github.com/golang/mock/gomock" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockMetaDataReader is a mock of MetaDataReader interface 14 | type MockMetaDataReader struct { 15 | ctrl *gomock.Controller 16 | recorder *MockMetaDataReaderMockRecorder 17 | } 18 | 19 | // MockMetaDataReaderMockRecorder is the mock recorder for MockMetaDataReader 20 | type MockMetaDataReaderMockRecorder struct { 21 | mock *MockMetaDataReader 22 | } 23 | 24 | // NewMockMetaDataReader creates a new mock instance 25 | func NewMockMetaDataReader(ctrl *gomock.Controller) *MockMetaDataReader { 26 | mock := &MockMetaDataReader{ctrl: ctrl} 27 | mock.recorder = &MockMetaDataReaderMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockMetaDataReader) EXPECT() *MockMetaDataReaderMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Metadata mocks base method 37 | func (m *MockMetaDataReader) Metadata() (workspace.Metadata, error) { 38 | ret := m.ctrl.Call(m, "Metadata") 39 | ret0, _ := ret[0].(workspace.Metadata) 40 | ret1, _ := ret[1].(error) 41 | return ret0, ret1 42 | } 43 | 44 | // Metadata indicates an expected call of Metadata 45 | func (mr *MockMetaDataReaderMockRecorder) Metadata() *gomock.Call { 46 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Metadata", reflect.TypeOf((*MockMetaDataReader)(nil).Metadata)) 47 | } 48 | -------------------------------------------------------------------------------- /workspace/metadata_test.go: -------------------------------------------------------------------------------- 1 | package workspace_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | "code.cloudfoundry.org/cfdev/workspace" 6 | "io/ioutil" 7 | "os" 8 | "path/filepath" 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | ) 12 | 13 | var _ = Describe("MetaData", func() { 14 | Context("reader returns", func() { 15 | var ( 16 | stateDir string 17 | ) 18 | 19 | BeforeEach(func() { 20 | var err error 21 | stateDir, err = ioutil.TempDir("", "tmp") 22 | Expect(err).ToNot(HaveOccurred()) 23 | 24 | metaDataPath := filepath.Join(stateDir, "metadata.yml") 25 | 26 | ioutil.WriteFile(metaDataPath, []byte(`--- 27 | compatibility_version: "v29" 28 | default_memory: 8192 29 | deployment_name: "cf" 30 | 31 | splash_message: is simply dummy text 32 | 33 | services: 34 | - name: Mysql 35 | flag_name: mysql 36 | default_deploy: true 37 | handle: deploy-mysql 38 | script: bin/deploy-mysql 39 | deployment: cf-mysql 40 | 41 | versions: 42 | - name: some-release 43 | version: v123-some-version 44 | - name: some-other-release 45 | version: v9.9.9`), 0777) 46 | }) 47 | 48 | AfterEach(func() { 49 | os.RemoveAll(stateDir) 50 | }) 51 | 52 | It("reports metadata correctly", func() { 53 | wk := workspace.New(config.Config{ 54 | StateDir: stateDir, 55 | }) 56 | 57 | metadata, err := wk.Metadata() 58 | Expect(err).ToNot(HaveOccurred()) 59 | 60 | Expect(metadata.Version).To(Equal("v29")) 61 | Expect(metadata.Message).To(Equal("is simply dummy text")) 62 | Expect(metadata.Versions[0].Name).To(Equal("some-release")) 63 | Expect(metadata.Versions[0].Value).To(Equal("v123-some-version")) 64 | }) 65 | }) 66 | }) 67 | 68 | -------------------------------------------------------------------------------- /cmd/provision/mocks/metadata_reader.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/provision (interfaces: MetaDataReader) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | workspace "code.cloudfoundry.org/cfdev/workspace" 9 | gomock "github.com/golang/mock/gomock" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockMetaDataReader is a mock of MetaDataReader interface 14 | type MockMetaDataReader struct { 15 | ctrl *gomock.Controller 16 | recorder *MockMetaDataReaderMockRecorder 17 | } 18 | 19 | // MockMetaDataReaderMockRecorder is the mock recorder for MockMetaDataReader 20 | type MockMetaDataReaderMockRecorder struct { 21 | mock *MockMetaDataReader 22 | } 23 | 24 | // NewMockMetaDataReader creates a new mock instance 25 | func NewMockMetaDataReader(ctrl *gomock.Controller) *MockMetaDataReader { 26 | mock := &MockMetaDataReader{ctrl: ctrl} 27 | mock.recorder = &MockMetaDataReaderMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockMetaDataReader) EXPECT() *MockMetaDataReaderMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Metadata mocks base method 37 | func (m *MockMetaDataReader) Metadata() (workspace.Metadata, error) { 38 | ret := m.ctrl.Call(m, "Metadata") 39 | ret0, _ := ret[0].(workspace.Metadata) 40 | ret1, _ := ret[1].(error) 41 | return ret0, ret1 42 | } 43 | 44 | // Metadata indicates an expected call of Metadata 45 | func (mr *MockMetaDataReaderMockRecorder) Metadata() *gomock.Call { 46 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Metadata", reflect.TypeOf((*MockMetaDataReader)(nil).Metadata)) 47 | } 48 | -------------------------------------------------------------------------------- /cmd/deploy-service/mocks/metadata_reader.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/deploy-service (interfaces: MetaDataReader) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | workspace "code.cloudfoundry.org/cfdev/workspace" 9 | gomock "github.com/golang/mock/gomock" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockMetaDataReader is a mock of MetaDataReader interface 14 | type MockMetaDataReader struct { 15 | ctrl *gomock.Controller 16 | recorder *MockMetaDataReaderMockRecorder 17 | } 18 | 19 | // MockMetaDataReaderMockRecorder is the mock recorder for MockMetaDataReader 20 | type MockMetaDataReaderMockRecorder struct { 21 | mock *MockMetaDataReader 22 | } 23 | 24 | // NewMockMetaDataReader creates a new mock instance 25 | func NewMockMetaDataReader(ctrl *gomock.Controller) *MockMetaDataReader { 26 | mock := &MockMetaDataReader{ctrl: ctrl} 27 | mock.recorder = &MockMetaDataReaderMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockMetaDataReader) EXPECT() *MockMetaDataReaderMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Metadata mocks base method 37 | func (m *MockMetaDataReader) Metadata() (workspace.Metadata, error) { 38 | ret := m.ctrl.Call(m, "Metadata") 39 | ret0, _ := ret[0].(workspace.Metadata) 40 | ret1, _ := ret[1].(error) 41 | return ret0, ret1 42 | } 43 | 44 | // Metadata indicates an expected call of Metadata 45 | func (mr *MockMetaDataReaderMockRecorder) Metadata() *gomock.Call { 46 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Metadata", reflect.TypeOf((*MockMetaDataReader)(nil).Metadata)) 47 | } 48 | -------------------------------------------------------------------------------- /cmd/stop/mocks/analytics.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/stop (interfaces: Analytics) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockAnalytics is a mock of Analytics interface 13 | type MockAnalytics struct { 14 | ctrl *gomock.Controller 15 | recorder *MockAnalyticsMockRecorder 16 | } 17 | 18 | // MockAnalyticsMockRecorder is the mock recorder for MockAnalytics 19 | type MockAnalyticsMockRecorder struct { 20 | mock *MockAnalytics 21 | } 22 | 23 | // NewMockAnalytics creates a new mock instance 24 | func NewMockAnalytics(ctrl *gomock.Controller) *MockAnalytics { 25 | mock := &MockAnalytics{ctrl: ctrl} 26 | mock.recorder = &MockAnalyticsMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockAnalytics) EXPECT() *MockAnalyticsMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Event mocks base method 36 | func (m *MockAnalytics) Event(arg0 string, arg1 ...map[string]interface{}) error { 37 | varargs := []interface{}{arg0} 38 | for _, a := range arg1 { 39 | varargs = append(varargs, a) 40 | } 41 | ret := m.ctrl.Call(m, "Event", varargs...) 42 | ret0, _ := ret[0].(error) 43 | return ret0 44 | } 45 | 46 | // Event indicates an expected call of Event 47 | func (mr *MockAnalyticsMockRecorder) Event(arg0 interface{}, arg1 ...interface{}) *gomock.Call { 48 | varargs := append([]interface{}{arg0}, arg1...) 49 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Event", reflect.TypeOf((*MockAnalytics)(nil).Event), varargs...) 50 | } 51 | -------------------------------------------------------------------------------- /cmd/deploy-service/mocks/analytics.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/stop (interfaces: Analytics) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockAnalytics is a mock of Analytics interface 13 | type MockAnalytics struct { 14 | ctrl *gomock.Controller 15 | recorder *MockAnalyticsMockRecorder 16 | } 17 | 18 | // MockAnalyticsMockRecorder is the mock recorder for MockAnalytics 19 | type MockAnalyticsMockRecorder struct { 20 | mock *MockAnalytics 21 | } 22 | 23 | // NewMockAnalytics creates a new mock instance 24 | func NewMockAnalytics(ctrl *gomock.Controller) *MockAnalytics { 25 | mock := &MockAnalytics{ctrl: ctrl} 26 | mock.recorder = &MockAnalyticsMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockAnalytics) EXPECT() *MockAnalyticsMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Event mocks base method 36 | func (m *MockAnalytics) Event(arg0 string, arg1 ...map[string]interface{}) error { 37 | varargs := []interface{}{arg0} 38 | for _, a := range arg1 { 39 | varargs = append(varargs, a) 40 | } 41 | ret := m.ctrl.Call(m, "Event", varargs...) 42 | ret0, _ := ret[0].(error) 43 | return ret0 44 | } 45 | 46 | // Event indicates an expected call of Event 47 | func (mr *MockAnalyticsMockRecorder) Event(arg0 interface{}, arg1 ...interface{}) *gomock.Call { 48 | varargs := append([]interface{}{arg0}, arg1...) 49 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Event", reflect.TypeOf((*MockAnalytics)(nil).Event), varargs...) 50 | } 51 | -------------------------------------------------------------------------------- /resource/retry/retry_test.go: -------------------------------------------------------------------------------- 1 | package retry_test 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "time" 7 | 8 | "code.cloudfoundry.org/cfdev/resource/retry" 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | ) 12 | 13 | var _ = Describe("Retry", func() { 14 | It("retries until success", func() { 15 | counter := 0 16 | fn := func() error { 17 | counter += 1 18 | if counter < 6 { 19 | return fmt.Errorf("failing") 20 | } 21 | return nil 22 | } 23 | retryFn := func(error) bool { return true } 24 | Expect(retry.Retry(fn, retryFn)).To(Succeed()) 25 | Expect(counter).To(Equal(6)) 26 | }) 27 | 28 | It("returns error if retryFn returns false", func() { 29 | fn := func() error { return fmt.Errorf("failing") } 30 | retryFn := func(error) bool { return false } 31 | 32 | Expect(retry.Retry(fn, retryFn)).To(MatchError("failing")) 33 | }) 34 | 35 | Describe("Retryable", func() { 36 | var buffer bytes.Buffer 37 | It("does not retry other errors", func() { 38 | counter := 0 39 | fn := func() error { 40 | counter++ 41 | return fmt.Errorf("failing") 42 | } 43 | 44 | Expect(retry.Retry(fn, retry.Retryable(10, time.Nanosecond, &buffer))).To(MatchError("failing")) 45 | Expect(counter).To(Equal(1)) 46 | Expect(buffer.String()).NotTo(ContainSubstring("Failed: Retrying:")) 47 | }) 48 | 49 | It("retries retyables a max number of times", func() { 50 | counter := 0 51 | fn := func() error { 52 | counter++ 53 | return retry.WrapAsRetryable(fmt.Errorf("failing")) 54 | } 55 | 56 | Expect(retry.Retry(fn, retry.Retryable(10, time.Nanosecond, &buffer))).To(MatchError("failing")) 57 | Expect(counter).To(Equal(10)) 58 | Expect(buffer.String()).To(ContainSubstring("Failed: Retrying:")) 59 | }) 60 | }) 61 | }) 62 | -------------------------------------------------------------------------------- /cmd/stop/mocks/vpnkit.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/stop (interfaces: VpnKit) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockVpnKit is a mock of VpnKit interface 13 | type MockVpnKit struct { 14 | ctrl *gomock.Controller 15 | recorder *MockVpnKitMockRecorder 16 | } 17 | 18 | // MockVpnKitMockRecorder is the mock recorder for MockVpnKit 19 | type MockVpnKitMockRecorder struct { 20 | mock *MockVpnKit 21 | } 22 | 23 | // NewMockVpnKit creates a new mock instance 24 | func NewMockVpnKit(ctrl *gomock.Controller) *MockVpnKit { 25 | mock := &MockVpnKit{ctrl: ctrl} 26 | mock.recorder = &MockVpnKitMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockVpnKit) EXPECT() *MockVpnKitMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Destroy mocks base method 36 | func (m *MockVpnKit) Destroy() error { 37 | ret := m.ctrl.Call(m, "Destroy") 38 | ret0, _ := ret[0].(error) 39 | return ret0 40 | } 41 | 42 | // Destroy indicates an expected call of Destroy 43 | func (mr *MockVpnKitMockRecorder) Destroy() *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Destroy", reflect.TypeOf((*MockVpnKit)(nil).Destroy)) 45 | } 46 | 47 | // Stop mocks base method 48 | func (m *MockVpnKit) Stop() error { 49 | ret := m.ctrl.Call(m, "Stop") 50 | ret0, _ := ret[0].(error) 51 | return ret0 52 | } 53 | 54 | // Stop indicates an expected call of Stop 55 | func (mr *MockVpnKitMockRecorder) Stop() *gomock.Call { 56 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockVpnKit)(nil).Stop)) 57 | } 58 | -------------------------------------------------------------------------------- /pkg/cfdevd/install.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/daemon" 5 | "fmt" 6 | "io" 7 | "os" 8 | "path/filepath" 9 | ) 10 | 11 | func install(programSrc string, args []string) error { 12 | var ( 13 | lctl = daemon.New("") 14 | label = "org.cloudfoundry.cfdevd" 15 | program = "/Library/PrivilegedHelperTools/org.cloudfoundry.cfdevd" 16 | programArgs = append([]string{program}, args...) 17 | ) 18 | 19 | cfdevdSpec := daemon.DaemonSpec{ 20 | Label: label, 21 | Program: program, 22 | ProgramArguments: programArgs, 23 | RunAtLoad: false, 24 | Sockets: map[string]string{ 25 | sockName: "/var/tmp/cfdevd.socket", 26 | }, 27 | StdoutPath: "/var/tmp/cfdevd.stdout.log", 28 | StderrPath: "/var/tmp/cfdevd.stderr.log", 29 | } 30 | 31 | isRunning, err := lctl.IsRunning(label) 32 | if err != nil { 33 | return fmt.Errorf("checking if analyticsd is running: %s", err) 34 | } 35 | 36 | if isRunning { 37 | return nil 38 | } 39 | 40 | if err := copyExecutable(programSrc, program); err != nil { 41 | return fmt.Errorf("failed to copy cfdevd: %s", err) 42 | } 43 | 44 | if err := lctl.AddDaemon(cfdevdSpec); err != nil { 45 | return fmt.Errorf("failed to install cfdevd: %s", err) 46 | } 47 | 48 | return nil 49 | } 50 | 51 | func copyExecutable(src string, dest string) error { 52 | if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil { 53 | return err 54 | } 55 | 56 | target, err := os.Create(dest) 57 | if err != nil { 58 | return err 59 | } 60 | defer target.Close() 61 | 62 | if err = os.Chmod(dest, 0744); err != nil { 63 | return err 64 | } 65 | 66 | binData, err := os.Open(src) 67 | if err != nil { 68 | return err 69 | } 70 | defer binData.Close() 71 | 72 | _, err = io.Copy(target, binData) 73 | return err 74 | } 75 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/mocks/cloud_controller_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/analyticsd/command (interfaces: CloudControllerClient) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | url "net/url" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockCloudControllerClient is a mock of CloudControllerClient interface 14 | type MockCloudControllerClient struct { 15 | ctrl *gomock.Controller 16 | recorder *MockCloudControllerClientMockRecorder 17 | } 18 | 19 | // MockCloudControllerClientMockRecorder is the mock recorder for MockCloudControllerClient 20 | type MockCloudControllerClientMockRecorder struct { 21 | mock *MockCloudControllerClient 22 | } 23 | 24 | // NewMockCloudControllerClient creates a new mock instance 25 | func NewMockCloudControllerClient(ctrl *gomock.Controller) *MockCloudControllerClient { 26 | mock := &MockCloudControllerClient{ctrl: ctrl} 27 | mock.recorder = &MockCloudControllerClientMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockCloudControllerClient) EXPECT() *MockCloudControllerClientMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Fetch mocks base method 37 | func (m *MockCloudControllerClient) Fetch(arg0 string, arg1 url.Values, arg2 interface{}) error { 38 | ret := m.ctrl.Call(m, "Fetch", arg0, arg1, arg2) 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // Fetch indicates an expected call of Fetch 44 | func (mr *MockCloudControllerClientMockRecorder) Fetch(arg0, arg1, arg2 interface{}) *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Fetch", reflect.TypeOf((*MockCloudControllerClient)(nil).Fetch), arg0, arg1, arg2) 46 | } 47 | -------------------------------------------------------------------------------- /cmd/start/mocks/env.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: Env) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockEnv is a mock of Env interface 13 | type MockEnv struct { 14 | ctrl *gomock.Controller 15 | recorder *MockEnvMockRecorder 16 | } 17 | 18 | // MockEnvMockRecorder is the mock recorder for MockEnv 19 | type MockEnvMockRecorder struct { 20 | mock *MockEnv 21 | } 22 | 23 | // NewMockEnv creates a new mock instance 24 | func NewMockEnv(ctrl *gomock.Controller) *MockEnv { 25 | mock := &MockEnv{ctrl: ctrl} 26 | mock.recorder = &MockEnvMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockEnv) EXPECT() *MockEnvMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // CreateDirs mocks base method 36 | func (m *MockEnv) CreateDirs() error { 37 | ret := m.ctrl.Call(m, "CreateDirs") 38 | ret0, _ := ret[0].(error) 39 | return ret0 40 | } 41 | 42 | // CreateDirs indicates an expected call of CreateDirs 43 | func (mr *MockEnvMockRecorder) CreateDirs() *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateDirs", reflect.TypeOf((*MockEnv)(nil).CreateDirs)) 45 | } 46 | 47 | // SetupState mocks base method 48 | func (m *MockEnv) SetupState(arg0 string) error { 49 | ret := m.ctrl.Call(m, "SetupState", arg0) 50 | ret0, _ := ret[0].(error) 51 | return ret0 52 | } 53 | 54 | // SetupState indicates an expected call of SetupState 55 | func (mr *MockEnvMockRecorder) SetupState(arg0 interface{}) *gomock.Call { 56 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetupState", reflect.TypeOf((*MockEnv)(nil).SetupState), arg0) 57 | } 58 | -------------------------------------------------------------------------------- /driver/ip_linux.go: -------------------------------------------------------------------------------- 1 | package driver 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | "encoding/json" 6 | "fmt" 7 | "io/ioutil" 8 | "os/exec" 9 | "path/filepath" 10 | ) 11 | 12 | func IP(cfg config.Config) (string, error) { 13 | var ( 14 | ipPath = filepath.Join(cfg.StateLinuxkit, "ip") 15 | macAddrPath = filepath.Join(cfg.StateLinuxkit, "mac-addr") 16 | vBridgeInfoPath = "/var/lib/libvirt/dnsmasq/virbr0.status" 17 | ) 18 | 19 | // The logic below is a bit of a hack. 20 | // Since the services will get started as root, the qemu files containing the ip address will be written as root. 21 | // We don't want to escalate to root every time we need the ip throughout the lifecycle of the program, so we write 22 | // the ip address as a normal file when we first get it. This logic is making an assumption that root privileges 23 | // has been retrieved as part of a prior step and has not yet timed out. 24 | data, err := ioutil.ReadFile(ipPath) 25 | if err == nil { 26 | return string(data), nil 27 | } 28 | 29 | macAddr, err := readAsSudo(macAddrPath) 30 | if err != nil { 31 | return "", err 32 | } 33 | 34 | vBridgeInfo, err := readAsSudo(vBridgeInfoPath) 35 | if err != nil { 36 | return "", err 37 | } 38 | 39 | var results []struct { 40 | IPAddr string `json:"ip-address"` 41 | MacAddr string `json:"mac-address"` 42 | } 43 | 44 | err = json.Unmarshal(vBridgeInfo, &results) 45 | if err != nil { 46 | return "", err 47 | } 48 | 49 | for _, result := range results { 50 | if result.MacAddr == string(macAddr) { 51 | ioutil.WriteFile(ipPath, []byte(result.IPAddr), 0600) 52 | 53 | return result.IPAddr, nil 54 | } 55 | } 56 | 57 | return "", fmt.Errorf("unable to find VM IP address from '%s'", vBridgeInfoPath) 58 | } 59 | 60 | func readAsSudo(path string) ([]byte, error) { 61 | return exec.Command("sudo", "-S", "cat", path).Output() 62 | } 63 | -------------------------------------------------------------------------------- /cmd/stop/mocks/analyticsd.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/stop (interfaces: AnalyticsD) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockAnalyticsD is a mock of AnalyticsD interface 13 | type MockAnalyticsD struct { 14 | ctrl *gomock.Controller 15 | recorder *MockAnalyticsDMockRecorder 16 | } 17 | 18 | // MockAnalyticsDMockRecorder is the mock recorder for MockAnalyticsD 19 | type MockAnalyticsDMockRecorder struct { 20 | mock *MockAnalyticsD 21 | } 22 | 23 | // NewMockAnalyticsD creates a new mock instance 24 | func NewMockAnalyticsD(ctrl *gomock.Controller) *MockAnalyticsD { 25 | mock := &MockAnalyticsD{ctrl: ctrl} 26 | mock.recorder = &MockAnalyticsDMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockAnalyticsD) EXPECT() *MockAnalyticsDMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Destroy mocks base method 36 | func (m *MockAnalyticsD) Destroy() error { 37 | ret := m.ctrl.Call(m, "Destroy") 38 | ret0, _ := ret[0].(error) 39 | return ret0 40 | } 41 | 42 | // Destroy indicates an expected call of Destroy 43 | func (mr *MockAnalyticsDMockRecorder) Destroy() *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Destroy", reflect.TypeOf((*MockAnalyticsD)(nil).Destroy)) 45 | } 46 | 47 | // Stop mocks base method 48 | func (m *MockAnalyticsD) Stop() error { 49 | ret := m.ctrl.Call(m, "Stop") 50 | ret0, _ := ret[0].(error) 51 | return ret0 52 | } 53 | 54 | // Stop indicates an expected call of Stop 55 | func (mr *MockAnalyticsDMockRecorder) Stop() *gomock.Call { 56 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockAnalyticsD)(nil).Stop)) 57 | } 58 | -------------------------------------------------------------------------------- /driver/hyperkit/network.go: -------------------------------------------------------------------------------- 1 | package hyperkit 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/daemon" 5 | "code.cloudfoundry.org/cfdev/driver" 6 | "fmt" 7 | "net" 8 | "path" 9 | "path/filepath" 10 | "time" 11 | ) 12 | 13 | func (d *Hyperkit) waitForNetworking() error { 14 | var ( 15 | ticker = time.NewTicker(time.Second) 16 | timeout = time.After(30 * time.Second) 17 | err error 18 | ) 19 | 20 | for { 21 | select { 22 | case <-ticker.C: 23 | var conn net.Conn 24 | conn, err = net.Dial("unix", filepath.Join(d.Config.VpnKitStateDir, "vpnkit_eth.sock")) 25 | if err == nil { 26 | conn.Close() 27 | return nil 28 | } 29 | case <-timeout: 30 | return fmt.Errorf("timed out connecting to vpnkit: %s", err) 31 | } 32 | } 33 | } 34 | 35 | func (d *Hyperkit) networkingDaemonSpec() daemon.DaemonSpec { 36 | return daemon.DaemonSpec{ 37 | Label: driver.VpnKitLabel, 38 | Program: path.Join(d.Config.BinaryDir, "vpnkit"), 39 | SessionType: "Background", 40 | ProgramArguments: []string{ 41 | path.Join(d.Config.CacheDir, "vpnkit"), 42 | "--ethernet", path.Join(d.Config.VpnKitStateDir, "vpnkit_eth.sock"), 43 | "--port", path.Join(d.Config.VpnKitStateDir, "vpnkit_port.sock"), 44 | "--vsock-path", path.Join(d.Config.StateLinuxkit, "connect"), 45 | "--http", path.Join(d.Config.VpnKitStateDir, "http_proxy.json"), 46 | "--host-names", "host.cfdev.sh", 47 | }, 48 | RunAtLoad: false, 49 | StdoutPath: path.Join(d.Config.LogDir, "vpnkit.stdout.log"), 50 | StderrPath: path.Join(d.Config.LogDir, "vpnkit.stderr.log"), 51 | } 52 | } 53 | 54 | func (d *Hyperkit) installCFDevDaemon() error { 55 | var ( 56 | executablePath = filepath.Join(d.Config.CacheDir, "cfdevd") 57 | timeSyncSocket = filepath.Join(d.Config.StateLinuxkit, "00000003.0000f3a4") 58 | ) 59 | 60 | return d.SudoShell.Run(executablePath, "install", "--timesyncSock", timeSyncSocket) 61 | } 62 | -------------------------------------------------------------------------------- /cmd/start/mocks/ui.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: UI) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | io "io" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockUI is a mock of UI interface 14 | type MockUI struct { 15 | ctrl *gomock.Controller 16 | recorder *MockUIMockRecorder 17 | } 18 | 19 | // MockUIMockRecorder is the mock recorder for MockUI 20 | type MockUIMockRecorder struct { 21 | mock *MockUI 22 | } 23 | 24 | // NewMockUI creates a new mock instance 25 | func NewMockUI(ctrl *gomock.Controller) *MockUI { 26 | mock := &MockUI{ctrl: ctrl} 27 | mock.recorder = &MockUIMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockUI) EXPECT() *MockUIMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Say mocks base method 37 | func (m *MockUI) Say(arg0 string, arg1 ...interface{}) { 38 | varargs := []interface{}{arg0} 39 | for _, a := range arg1 { 40 | varargs = append(varargs, a) 41 | } 42 | m.ctrl.Call(m, "Say", varargs...) 43 | } 44 | 45 | // Say indicates an expected call of Say 46 | func (mr *MockUIMockRecorder) Say(arg0 interface{}, arg1 ...interface{}) *gomock.Call { 47 | varargs := append([]interface{}{arg0}, arg1...) 48 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Say", reflect.TypeOf((*MockUI)(nil).Say), varargs...) 49 | } 50 | 51 | // Writer mocks base method 52 | func (m *MockUI) Writer() io.Writer { 53 | ret := m.ctrl.Call(m, "Writer") 54 | ret0, _ := ret[0].(io.Writer) 55 | return ret0 56 | } 57 | 58 | // Writer indicates an expected call of Writer 59 | func (mr *MockUIMockRecorder) Writer() *gomock.Call { 60 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Writer", reflect.TypeOf((*MockUI)(nil).Writer)) 61 | } 62 | -------------------------------------------------------------------------------- /cmd/provision/mocks/ui.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/provision (interfaces: UI) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | io "io" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockUI is a mock of UI interface 14 | type MockUI struct { 15 | ctrl *gomock.Controller 16 | recorder *MockUIMockRecorder 17 | } 18 | 19 | // MockUIMockRecorder is the mock recorder for MockUI 20 | type MockUIMockRecorder struct { 21 | mock *MockUI 22 | } 23 | 24 | // NewMockUI creates a new mock instance 25 | func NewMockUI(ctrl *gomock.Controller) *MockUI { 26 | mock := &MockUI{ctrl: ctrl} 27 | mock.recorder = &MockUIMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockUI) EXPECT() *MockUIMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Say mocks base method 37 | func (m *MockUI) Say(arg0 string, arg1 ...interface{}) { 38 | varargs := []interface{}{arg0} 39 | for _, a := range arg1 { 40 | varargs = append(varargs, a) 41 | } 42 | m.ctrl.Call(m, "Say", varargs...) 43 | } 44 | 45 | // Say indicates an expected call of Say 46 | func (mr *MockUIMockRecorder) Say(arg0 interface{}, arg1 ...interface{}) *gomock.Call { 47 | varargs := append([]interface{}{arg0}, arg1...) 48 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Say", reflect.TypeOf((*MockUI)(nil).Say), varargs...) 49 | } 50 | 51 | // Writer mocks base method 52 | func (m *MockUI) Writer() io.Writer { 53 | ret := m.ctrl.Call(m, "Writer") 54 | ret0, _ := ret[0].(io.Writer) 55 | return ret0 56 | } 57 | 58 | // Writer indicates an expected call of Writer 59 | func (mr *MockUIMockRecorder) Writer() *gomock.Call { 60 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Writer", reflect.TypeOf((*MockUI)(nil).Writer)) 61 | } 62 | -------------------------------------------------------------------------------- /cmd/deploy-service/mocks/ui.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/deploy-service (interfaces: UI) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | io "io" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockUI is a mock of UI interface 14 | type MockUI struct { 15 | ctrl *gomock.Controller 16 | recorder *MockUIMockRecorder 17 | } 18 | 19 | // MockUIMockRecorder is the mock recorder for MockUI 20 | type MockUIMockRecorder struct { 21 | mock *MockUI 22 | } 23 | 24 | // NewMockUI creates a new mock instance 25 | func NewMockUI(ctrl *gomock.Controller) *MockUI { 26 | mock := &MockUI{ctrl: ctrl} 27 | mock.recorder = &MockUIMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockUI) EXPECT() *MockUIMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Say mocks base method 37 | func (m *MockUI) Say(arg0 string, arg1 ...interface{}) { 38 | varargs := []interface{}{arg0} 39 | for _, a := range arg1 { 40 | varargs = append(varargs, a) 41 | } 42 | m.ctrl.Call(m, "Say", varargs...) 43 | } 44 | 45 | // Say indicates an expected call of Say 46 | func (mr *MockUIMockRecorder) Say(arg0 interface{}, arg1 ...interface{}) *gomock.Call { 47 | varargs := append([]interface{}{arg0}, arg1...) 48 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Say", reflect.TypeOf((*MockUI)(nil).Say), varargs...) 49 | } 50 | 51 | // Writer mocks base method 52 | func (m *MockUI) Writer() io.Writer { 53 | ret := m.ctrl.Call(m, "Writer") 54 | ret0, _ := ret[0].(io.Writer) 55 | return ret0 56 | } 57 | 58 | // Writer indicates an expected call of Writer 59 | func (mr *MockUIMockRecorder) Writer() *gomock.Call { 60 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Writer", reflect.TypeOf((*MockUI)(nil).Writer)) 61 | } 62 | -------------------------------------------------------------------------------- /cfanalytics/mocks/analytics_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: gopkg.in/segmentio/analytics-go.v3 (interfaces: Client) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | analytics_go_v3 "gopkg.in/segmentio/analytics-go.v3" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockClient is a mock of Client interface 14 | type MockClient struct { 15 | ctrl *gomock.Controller 16 | recorder *MockClientMockRecorder 17 | } 18 | 19 | // MockClientMockRecorder is the mock recorder for MockClient 20 | type MockClientMockRecorder struct { 21 | mock *MockClient 22 | } 23 | 24 | // NewMockClient creates a new mock instance 25 | func NewMockClient(ctrl *gomock.Controller) *MockClient { 26 | mock := &MockClient{ctrl: ctrl} 27 | mock.recorder = &MockClientMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockClient) EXPECT() *MockClientMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Close mocks base method 37 | func (m *MockClient) Close() error { 38 | ret := m.ctrl.Call(m, "Close") 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // Close indicates an expected call of Close 44 | func (mr *MockClientMockRecorder) Close() *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockClient)(nil).Close)) 46 | } 47 | 48 | // Enqueue mocks base method 49 | func (m *MockClient) Enqueue(arg0 analytics_go_v3.Message) error { 50 | ret := m.ctrl.Call(m, "Enqueue", arg0) 51 | ret0, _ := ret[0].(error) 52 | return ret0 53 | } 54 | 55 | // Enqueue indicates an expected call of Enqueue 56 | func (mr *MockClientMockRecorder) Enqueue(arg0 interface{}) *gomock.Call { 57 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Enqueue", reflect.TypeOf((*MockClient)(nil).Enqueue), arg0) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/analyticsd/daemon/mocks/analytics.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: gopkg.in/segmentio/analytics-go.v3 (interfaces: Client) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | analytics_go_v3 "gopkg.in/segmentio/analytics-go.v3" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockClient is a mock of Client interface 14 | type MockClient struct { 15 | ctrl *gomock.Controller 16 | recorder *MockClientMockRecorder 17 | } 18 | 19 | // MockClientMockRecorder is the mock recorder for MockClient 20 | type MockClientMockRecorder struct { 21 | mock *MockClient 22 | } 23 | 24 | // NewMockClient creates a new mock instance 25 | func NewMockClient(ctrl *gomock.Controller) *MockClient { 26 | mock := &MockClient{ctrl: ctrl} 27 | mock.recorder = &MockClientMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockClient) EXPECT() *MockClientMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Close mocks base method 37 | func (m *MockClient) Close() error { 38 | ret := m.ctrl.Call(m, "Close") 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // Close indicates an expected call of Close 44 | func (mr *MockClientMockRecorder) Close() *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockClient)(nil).Close)) 46 | } 47 | 48 | // Enqueue mocks base method 49 | func (m *MockClient) Enqueue(arg0 analytics_go_v3.Message) error { 50 | ret := m.ctrl.Call(m, "Enqueue", arg0) 51 | ret0, _ := ret[0].(error) 52 | return ret0 53 | } 54 | 55 | // Enqueue indicates an expected call of Enqueue 56 | func (mr *MockClientMockRecorder) Enqueue(arg0 interface{}) *gomock.Call { 57 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Enqueue", reflect.TypeOf((*MockClient)(nil).Enqueue), arg0) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/analyticsd/segment/mocks/analytics.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: gopkg.in/segmentio/analytics-go.v3 (interfaces: Client) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | analytics_go_v3 "gopkg.in/segmentio/analytics-go.v3" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockClient is a mock of Client interface 14 | type MockClient struct { 15 | ctrl *gomock.Controller 16 | recorder *MockClientMockRecorder 17 | } 18 | 19 | // MockClientMockRecorder is the mock recorder for MockClient 20 | type MockClientMockRecorder struct { 21 | mock *MockClient 22 | } 23 | 24 | // NewMockClient creates a new mock instance 25 | func NewMockClient(ctrl *gomock.Controller) *MockClient { 26 | mock := &MockClient{ctrl: ctrl} 27 | mock.recorder = &MockClientMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockClient) EXPECT() *MockClientMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // Close mocks base method 37 | func (m *MockClient) Close() error { 38 | ret := m.ctrl.Call(m, "Close") 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // Close indicates an expected call of Close 44 | func (mr *MockClientMockRecorder) Close() *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockClient)(nil).Close)) 46 | } 47 | 48 | // Enqueue mocks base method 49 | func (m *MockClient) Enqueue(arg0 analytics_go_v3.Message) error { 50 | ret := m.ctrl.Call(m, "Enqueue", arg0) 51 | ret0, _ := ret[0].(error) 52 | return ret0 53 | } 54 | 55 | // Enqueue indicates an expected call of Enqueue 56 | func (mr *MockClientMockRecorder) Enqueue(arg0 interface{}) *gomock.Call { 57 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Enqueue", reflect.TypeOf((*MockClient)(nil).Enqueue), arg0) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/servicew/acceptance/integration_test.go: -------------------------------------------------------------------------------- 1 | package acceptance_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/servicew/client" 5 | "code.cloudfoundry.org/cfdev/pkg/servicew/config" 6 | "fmt" 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | "gopkg.in/yaml.v2" 10 | "io/ioutil" 11 | "os" 12 | "runtime" 13 | "strings" 14 | "time" 15 | ) 16 | 17 | var _ = Describe("ServiceWrapper Lifecycle", func() { 18 | 19 | var ( 20 | tempDir string 21 | swc *client.ServiceWrapper 22 | label = "org.cfdev.servicew.simple" 23 | ) 24 | 25 | BeforeEach(func() { 26 | var err error 27 | tempDir, err = ioutil.TempDir("", "cfdev-service-wrapper-") 28 | Expect(err).NotTo(HaveOccurred()) 29 | 30 | swc = client.New(binaryPath, tempDir) 31 | }) 32 | 33 | AfterEach(func() { 34 | swc.Stop(label) 35 | swc.Uninstall(label) 36 | os.RemoveAll(tempDir) 37 | }) 38 | 39 | It("installs, runs, and remove services", func() { 40 | Expect(swc.IsRunning(label)).To(BeFalse()) 41 | 42 | contents, err := ioutil.ReadFile(fixturePath(fmt.Sprintf("simple-%s.yml", runtime.GOOS))) 43 | Expect(err).NotTo(HaveOccurred()) 44 | 45 | var cfg config.Config 46 | yaml.Unmarshal(contents, &cfg) 47 | err = swc.Install(cfg) 48 | Expect(err).NotTo(HaveOccurred()) 49 | 50 | Expect(swc.IsRunning(label)).To(BeFalse()) 51 | 52 | err = swc.Start(label) 53 | Expect(err).NotTo(HaveOccurred()) 54 | 55 | Eventually(func() bool { 56 | isRunning, _ := swc.IsRunning(label) 57 | return isRunning 58 | }, 10*time.Second).Should(BeTrue()) 59 | 60 | if runtime.GOOS != "windows" { 61 | output := run("bash", "-c", "ps aux | grep 'sleep 12345'") 62 | Expect(strings.TrimSpace(output)).NotTo(BeEmpty()) 63 | } 64 | 65 | err = swc.Stop(label) 66 | Expect(err).NotTo(HaveOccurred()) 67 | Expect(swc.IsRunning(label)).To(BeFalse()) 68 | 69 | err = swc.Uninstall(label) 70 | Expect(swc.IsRunning(label)).To(BeFalse()) 71 | }) 72 | }) 73 | -------------------------------------------------------------------------------- /cmd/stop/mocks/linuxkit.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/stop (interfaces: Hypervisor) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockHypervisor is a mock of Hypervisor interface 13 | type MockHypervisor struct { 14 | ctrl *gomock.Controller 15 | recorder *MockHypervisorMockRecorder 16 | } 17 | 18 | // MockHypervisorMockRecorder is the mock recorder for MockHypervisor 19 | type MockHypervisorMockRecorder struct { 20 | mock *MockHypervisor 21 | } 22 | 23 | // NewMockHypervisor creates a new mock instance 24 | func NewMockHypervisor(ctrl *gomock.Controller) *MockHypervisor { 25 | mock := &MockHypervisor{ctrl: ctrl} 26 | mock.recorder = &MockHypervisorMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockHypervisor) EXPECT() *MockHypervisorMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Destroy mocks base method 36 | func (m *MockHypervisor) Destroy(arg0 string) error { 37 | ret := m.ctrl.Call(m, "Destroy", arg0) 38 | ret0, _ := ret[0].(error) 39 | return ret0 40 | } 41 | 42 | // Destroy indicates an expected call of Destroy 43 | func (mr *MockHypervisorMockRecorder) Destroy(arg0 interface{}) *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Destroy", reflect.TypeOf((*MockHypervisor)(nil).Destroy), arg0) 45 | } 46 | 47 | // Stop mocks base method 48 | func (m *MockHypervisor) Stop(arg0 string) error { 49 | ret := m.ctrl.Call(m, "Stop", arg0) 50 | ret0, _ := ret[0].(error) 51 | return ret0 52 | } 53 | 54 | // Stop indicates an expected call of Stop 55 | func (mr *MockHypervisorMockRecorder) Stop(arg0 interface{}) *gomock.Call { 56 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockHypervisor)(nil).Stop), arg0) 57 | } 58 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/org_create_test.go: -------------------------------------------------------------------------------- 1 | package command_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/command" 5 | commandMocks "code.cloudfoundry.org/cfdev/pkg/analyticsd/command/mocks" 6 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 7 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment/mocks" 8 | "github.com/golang/mock/gomock" 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | "gopkg.in/segmentio/analytics-go.v3" 12 | "io/ioutil" 13 | "log" 14 | "time" 15 | ) 16 | 17 | var _ = Describe("OrgCreate", func() { 18 | var ( 19 | cmd *command.OrgCreate 20 | mockController *gomock.Controller 21 | mockAnalytics *mocks.MockClient 22 | mockCCClient *commandMocks.MockCloudControllerClient 23 | ) 24 | 25 | BeforeEach(func() { 26 | mockController = gomock.NewController(GinkgoT()) 27 | mockAnalytics = mocks.NewMockClient(mockController) 28 | mockCCClient = commandMocks.NewMockCloudControllerClient(mockController) 29 | segmentClient := segment.New( 30 | mockAnalytics, 31 | "some-user-uuid", 32 | "some-version", 33 | "some-os-version", 34 | time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC), 35 | ) 36 | 37 | cmd = &command.OrgCreate{ 38 | Logger: log.New(ioutil.Discard, "", log.LstdFlags), 39 | CCClient: mockCCClient, 40 | AnalyticsClient: segmentClient, 41 | } 42 | }) 43 | 44 | AfterEach(func() { 45 | mockController.Finish() 46 | }) 47 | 48 | Context("when org is created", func() { 49 | It("sends the org information to segment.io", func() { 50 | mockAnalytics.EXPECT().Enqueue(gomock.Any()).Do(func(event analytics.Track) { 51 | Expect(event.UserId).To(Equal("some-user-uuid")) 52 | Expect(event.Event).To(Equal("org created")) 53 | Expect(event.Timestamp).To(Equal(time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC))) 54 | }) 55 | 56 | 57 | body := []byte("") 58 | 59 | Expect(cmd.HandleResponse(body)).NotTo(HaveOccurred()) 60 | }) 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/route_create_test.go: -------------------------------------------------------------------------------- 1 | package command_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/command" 5 | commandMocks "code.cloudfoundry.org/cfdev/pkg/analyticsd/command/mocks" 6 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 7 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment/mocks" 8 | "github.com/golang/mock/gomock" 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | "gopkg.in/segmentio/analytics-go.v3" 12 | "io/ioutil" 13 | "log" 14 | "time" 15 | ) 16 | 17 | var _ = Describe("RouteCreate", func() { 18 | var ( 19 | cmd *command.RouteCreate 20 | mockController *gomock.Controller 21 | mockAnalytics *mocks.MockClient 22 | mockCCClient *commandMocks.MockCloudControllerClient 23 | ) 24 | 25 | BeforeEach(func() { 26 | mockController = gomock.NewController(GinkgoT()) 27 | mockAnalytics = mocks.NewMockClient(mockController) 28 | mockCCClient = commandMocks.NewMockCloudControllerClient(mockController) 29 | segmentClient := segment.New( 30 | mockAnalytics, 31 | "some-user-uuid", 32 | "some-version", 33 | "some-os-version", 34 | time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC), 35 | ) 36 | 37 | cmd = &command.RouteCreate{ 38 | Logger: log.New(ioutil.Discard, "", log.LstdFlags), 39 | CCClient: mockCCClient, 40 | AnalyticsClient: segmentClient, 41 | } 42 | }) 43 | 44 | AfterEach(func() { 45 | mockController.Finish() 46 | }) 47 | 48 | Context("when route is created", func() { 49 | It("sends the route information to segment.io", func() { 50 | mockAnalytics.EXPECT().Enqueue(gomock.Any()).Do(func(event analytics.Track) { 51 | Expect(event.UserId).To(Equal("some-user-uuid")) 52 | Expect(event.Event).To(Equal("created route")) 53 | Expect(event.Timestamp).To(Equal(time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC))) 54 | }) 55 | 56 | 57 | body := []byte("") 58 | 59 | Expect(cmd.HandleResponse(body)).NotTo(HaveOccurred()) 60 | }) 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/space_create_test.go: -------------------------------------------------------------------------------- 1 | package command_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/command" 5 | commandMocks "code.cloudfoundry.org/cfdev/pkg/analyticsd/command/mocks" 6 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 7 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment/mocks" 8 | "github.com/golang/mock/gomock" 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | "gopkg.in/segmentio/analytics-go.v3" 12 | "io/ioutil" 13 | "log" 14 | "time" 15 | ) 16 | 17 | var _ = Describe("SpaceCreate", func() { 18 | var ( 19 | cmd *command.SpaceCreate 20 | mockController *gomock.Controller 21 | mockAnalytics *mocks.MockClient 22 | mockCCClient *commandMocks.MockCloudControllerClient 23 | ) 24 | 25 | BeforeEach(func() { 26 | mockController = gomock.NewController(GinkgoT()) 27 | mockAnalytics = mocks.NewMockClient(mockController) 28 | mockCCClient = commandMocks.NewMockCloudControllerClient(mockController) 29 | 30 | segmentClient := segment.New( 31 | mockAnalytics, 32 | "some-user-uuid", 33 | "some-version", 34 | "some-os-version", 35 | time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC), 36 | ) 37 | 38 | cmd = &command.SpaceCreate{ 39 | Logger: log.New(ioutil.Discard, "", log.LstdFlags), 40 | CCClient: mockCCClient, 41 | AnalyticsClient: segmentClient, 42 | } 43 | }) 44 | 45 | AfterEach(func() { 46 | mockController.Finish() 47 | }) 48 | 49 | Context("when space is created", func() { 50 | It("sends the space information to segment.io", func() { 51 | mockAnalytics.EXPECT().Enqueue(gomock.Any()).Do(func(event analytics.Track) { 52 | Expect(event.UserId).To(Equal("some-user-uuid")) 53 | Expect(event.Event).To(Equal("space created")) 54 | Expect(event.Timestamp).To(Equal(time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC))) 55 | }) 56 | 57 | body := []byte("") 58 | 59 | Expect(cmd.HandleResponse(body)).NotTo(HaveOccurred()) 60 | }) 61 | }) 62 | }) 63 | -------------------------------------------------------------------------------- /cmd/stop/mocks/launchd.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/stop (interfaces: Launchd) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | daemon "code.cloudfoundry.org/cfdev/daemon" 9 | gomock "github.com/golang/mock/gomock" 10 | reflect "reflect" 11 | ) 12 | 13 | // MockLaunchd is a mock of Launchd interface 14 | type MockLaunchd struct { 15 | ctrl *gomock.Controller 16 | recorder *MockLaunchdMockRecorder 17 | } 18 | 19 | // MockLaunchdMockRecorder is the mock recorder for MockLaunchd 20 | type MockLaunchdMockRecorder struct { 21 | mock *MockLaunchd 22 | } 23 | 24 | // NewMockLaunchd creates a new mock instance 25 | func NewMockLaunchd(ctrl *gomock.Controller) *MockLaunchd { 26 | mock := &MockLaunchd{ctrl: ctrl} 27 | mock.recorder = &MockLaunchdMockRecorder{mock} 28 | return mock 29 | } 30 | 31 | // EXPECT returns an object that allows the caller to indicate expected use 32 | func (m *MockLaunchd) EXPECT() *MockLaunchdMockRecorder { 33 | return m.recorder 34 | } 35 | 36 | // RemoveDaemon mocks base method 37 | func (m *MockLaunchd) RemoveDaemon(arg0 daemon.DaemonSpec) error { 38 | ret := m.ctrl.Call(m, "RemoveDaemon", arg0) 39 | ret0, _ := ret[0].(error) 40 | return ret0 41 | } 42 | 43 | // RemoveDaemon indicates an expected call of RemoveDaemon 44 | func (mr *MockLaunchdMockRecorder) RemoveDaemon(arg0 interface{}) *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveDaemon", reflect.TypeOf((*MockLaunchd)(nil).RemoveDaemon), arg0) 46 | } 47 | 48 | // Stop mocks base method 49 | func (m *MockLaunchd) Stop(arg0 daemon.DaemonSpec) error { 50 | ret := m.ctrl.Call(m, "Stop", arg0) 51 | ret0, _ := ret[0].(error) 52 | return ret0 53 | } 54 | 55 | // Stop indicates an expected call of Stop 56 | func (mr *MockLaunchdMockRecorder) Stop(arg0 interface{}) *gomock.Call { 57 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockLaunchd)(nil).Stop), arg0) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/cfdevd/cmd/unimplemented_test.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package cmd_test 4 | 5 | import ( 6 | "io/ioutil" 7 | "net" 8 | "os" 9 | "path/filepath" 10 | 11 | "code.cloudfoundry.org/cfdev/pkg/cfdevd/cmd" 12 | . "github.com/onsi/ginkgo" 13 | . "github.com/onsi/gomega" 14 | ) 15 | 16 | var _ = Describe("UnimplementedCommand", func() { 17 | Describe("Execute", func() { 18 | var ( 19 | ln *net.UnixListener 20 | socketDir string 21 | addr *net.UnixAddr 22 | ) 23 | 24 | BeforeEach(func() { 25 | var err error 26 | socketDir, err = ioutil.TempDir(os.Getenv("TMPDIR"), "socket") 27 | Expect(err).NotTo(HaveOccurred()) 28 | addr = &net.UnixAddr{ 29 | Name: filepath.Join(socketDir, "some.socket"), 30 | } 31 | ln, err = net.ListenUnix("unix", addr) 32 | }) 33 | 34 | AfterEach(func() { 35 | Expect(os.RemoveAll(socketDir)).To(Succeed()) 36 | Expect(ln.Close()).To(Succeed()) 37 | }) 38 | 39 | It("returns error code 33", func(done Done) { 40 | unimplemented := &cmd.UnimplementedCommand{ 41 | Logger: GinkgoWriter, 42 | } 43 | go func() { 44 | defer GinkgoRecover() 45 | conn, err := ln.Accept() 46 | Expect(err).NotTo(HaveOccurred()) 47 | defer conn.Close() 48 | data := make([]byte, 1, 1) 49 | _, err = conn.Read(data) 50 | Expect(err).NotTo(HaveOccurred()) 51 | Expect(data[0]).To(Equal(uint8(33))) 52 | close(done) 53 | }() 54 | conn, err := net.DialUnix("unix", nil, addr) 55 | Expect(err).NotTo(HaveOccurred()) 56 | defer conn.Close() 57 | Expect(unimplemented.Execute(conn)).To(Succeed()) 58 | }) 59 | 60 | It("returns an error when it cannot write message", func() { 61 | unimplemented := &cmd.UnimplementedCommand{ 62 | Logger: GinkgoWriter, 63 | } 64 | conn, err := net.DialUnix("unix", nil, addr) 65 | Expect(err).NotTo(HaveOccurred()) 66 | conn.Close() 67 | Expect(unimplemented.Execute(conn).Error()).To(ContainSubstring("failed to write error code to connection")) 68 | }) 69 | }) 70 | }) 71 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/app_crash_test.go: -------------------------------------------------------------------------------- 1 | package command_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/command" 5 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 6 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment/mocks" 7 | "github.com/golang/mock/gomock" 8 | . "github.com/onsi/ginkgo" 9 | . "github.com/onsi/gomega" 10 | "gopkg.in/segmentio/analytics-go.v3" 11 | "io/ioutil" 12 | "log" 13 | "time" 14 | ) 15 | 16 | var _ = Describe("AppCrash", func() { 17 | var ( 18 | cmd *command.AppCrash 19 | mockController *gomock.Controller 20 | mockAnalytics *mocks.MockClient 21 | ) 22 | 23 | BeforeEach(func() { 24 | mockController = gomock.NewController(GinkgoT()) 25 | mockAnalytics = mocks.NewMockClient(mockController) 26 | segmentClient := segment.New( 27 | mockAnalytics, 28 | "some-user-uuid", 29 | "some-version", 30 | "some-os-version", 31 | time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC), 32 | ) 33 | 34 | cmd = &command.AppCrash{ 35 | Logger: log.New(ioutil.Discard, "", log.LstdFlags), 36 | AnalyticsClient: segmentClient, 37 | } 38 | }) 39 | 40 | AfterEach(func() { 41 | mockController.Finish() 42 | }) 43 | 44 | Context("when an app crash event occurs", func() { 45 | It("sends the the crash event to segment.io", func() { 46 | mockAnalytics.EXPECT().Enqueue(gomock.Any()).Do(func(event analytics.Track) { 47 | Expect(event.UserId).To(Equal("some-user-uuid")) 48 | Expect(event.Event).To(Equal("app push failed")) 49 | Expect(event.Timestamp).To(Equal(time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC))) 50 | }) 51 | 52 | body := []byte(` 53 | { 54 | "instance": "d73d6816-3101-4efb-4a9b-c4c1", 55 | "index": 0, 56 | "cell_id": "f5002113-527c-4bf9-b5e4-867f68a4ecfc", 57 | "exit_description": "APP/PROC/WEB: Exited with status 1", 58 | "reason": "CRASHED" 59 | }`) 60 | 61 | cmd.HandleResponse(body) 62 | }) 63 | }) 64 | }) 65 | -------------------------------------------------------------------------------- /pkg/cfdevd/networkd/ip_aliaser.go: -------------------------------------------------------------------------------- 1 | package networkd 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | "os/exec" 8 | "strings" 9 | ) 10 | 11 | const loopback = "lo0" 12 | 13 | type HostNetD struct{} 14 | 15 | func (*HostNetD) AddLoopbackAliases(addrs ...string) error { 16 | fmt.Println("Setting up IP aliases for the BOSH Director & CF Router (requires administrator privileges)") 17 | 18 | if err := createInterface(); err != nil { 19 | return err 20 | } 21 | 22 | for _, addr := range addrs { 23 | exists, err := aliasExists(addr) 24 | 25 | if err != nil { 26 | return err 27 | } 28 | 29 | if exists { 30 | continue 31 | } 32 | 33 | err = addAlias(addr) 34 | if err != nil { 35 | return err 36 | } 37 | } 38 | return nil 39 | } 40 | 41 | func (*HostNetD) RemoveLoopbackAliases(addrs ...string) error { 42 | for _, addr := range addrs { 43 | if exists, err := aliasExists(addr); err != nil { 44 | return err 45 | } else if exists { 46 | if err := removeAlias(addr); err != nil { 47 | return fmt.Errorf("removing alias %s: %s", addr, err) 48 | } 49 | } 50 | } 51 | return nil 52 | } 53 | 54 | func addAlias(alias string) error { 55 | cmd := exec.Command("sudo", "ifconfig", loopback, "add", alias+"/32") 56 | cmd.Stdout = os.Stdout 57 | cmd.Stderr = os.Stderr 58 | cmd.Stdin = os.Stdin 59 | 60 | return cmd.Run() 61 | } 62 | 63 | func createInterface() error { 64 | return nil 65 | } 66 | 67 | func aliasExists(alias string) (bool, error) { 68 | addrs, err := net.InterfaceAddrs() 69 | if err != nil { 70 | return false, fmt.Errorf("getting interface addrs: %s", err) 71 | } 72 | for _, addr := range addrs { 73 | if strings.Contains(addr.String(), alias) { 74 | return true, nil 75 | } 76 | } 77 | 78 | return false, nil 79 | } 80 | 81 | func removeAlias(alias string) error { 82 | cmd := exec.Command("sudo", "ifconfig", loopback, "inet", alias+"/32", "remove") 83 | cmd.Stdout = os.Stdout 84 | cmd.Stderr = os.Stderr 85 | cmd.Stdin = os.Stdin 86 | 87 | return cmd.Run() 88 | } 89 | -------------------------------------------------------------------------------- /pkg/analyticsd/command/service_broker_create_test.go: -------------------------------------------------------------------------------- 1 | package command_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/command" 5 | commandMocks "code.cloudfoundry.org/cfdev/pkg/analyticsd/command/mocks" 6 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 7 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment/mocks" 8 | "github.com/golang/mock/gomock" 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | "gopkg.in/segmentio/analytics-go.v3" 12 | "io/ioutil" 13 | "log" 14 | "time" 15 | ) 16 | 17 | var _ = Describe("ServiceBrokerCreate", func() { 18 | var ( 19 | cmd *command.ServiceBrokerCreate 20 | mockController *gomock.Controller 21 | mockAnalytics *mocks.MockClient 22 | mockCCClient *commandMocks.MockCloudControllerClient 23 | ) 24 | 25 | BeforeEach(func() { 26 | mockController = gomock.NewController(GinkgoT()) 27 | mockAnalytics = mocks.NewMockClient(mockController) 28 | mockCCClient = commandMocks.NewMockCloudControllerClient(mockController) 29 | segmentClient := segment.New( 30 | mockAnalytics, 31 | "some-user-uuid", 32 | "some-version", 33 | "some-os-version", 34 | time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC), 35 | ) 36 | 37 | cmd = &command.ServiceBrokerCreate{ 38 | Logger: log.New(ioutil.Discard, "", log.LstdFlags), 39 | CCClient: mockCCClient, 40 | AnalyticsClient: segmentClient, 41 | } 42 | }) 43 | 44 | AfterEach(func() { 45 | mockController.Finish() 46 | }) 47 | 48 | Context("when service broker is created", func() { 49 | It("sends the route information to segment.io", func() { 50 | mockAnalytics.EXPECT().Enqueue(gomock.Any()).Do(func(event analytics.Track) { 51 | Expect(event.UserId).To(Equal("some-user-uuid")) 52 | Expect(event.Event).To(Equal("created service broker")) 53 | Expect(event.Timestamp).To(Equal(time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC))) 54 | }) 55 | 56 | body := []byte("") 57 | 58 | Expect(cmd.HandleResponse(body)).NotTo(HaveOccurred()) 59 | }) 60 | }) 61 | }) 62 | -------------------------------------------------------------------------------- /pkg/cfdevd/cmd/cmd_test.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package cmd_test 4 | 5 | import ( 6 | "bytes" 7 | 8 | "code.cloudfoundry.org/cfdev/pkg/cfdevd/cmd" 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | ) 12 | 13 | var _ = Describe("cmd", func() { 14 | It("return an UnimplementedCommand when given a 7", func() { 15 | badMessage := bytes.NewReader([]byte{uint8(7)}) 16 | 17 | badCommand, err := cmd.UnmarshalCommand(badMessage) 18 | 19 | Expect(err).NotTo(HaveOccurred()) 20 | switch v := badCommand.(type) { 21 | case *cmd.UnimplementedCommand: 22 | Expect(v.Instruction).To(Equal(uint8(7))) 23 | Expect(v.Logger).ToNot(BeNil()) 24 | default: 25 | Fail("wrong type!") 26 | } 27 | }) 28 | 29 | It("returns an BindCommand when given a 6", func() { 30 | message := bytes.NewReader([]byte{uint8(6)}) 31 | 32 | command, err := cmd.UnmarshalCommand(message) 33 | 34 | Expect(err).NotTo(HaveOccurred()) 35 | switch command.(type) { 36 | case *cmd.BindCommand: 37 | default: 38 | Fail("wrong type!") 39 | } 40 | }) 41 | 42 | It("returns an UninstallCommand when given a 1", func() { 43 | message := bytes.NewReader([]byte{uint8(1)}) 44 | 45 | command, err := cmd.UnmarshalCommand(message) 46 | 47 | Expect(err).NotTo(HaveOccurred()) 48 | switch command.(type) { 49 | case *cmd.UninstallCommand: 50 | default: 51 | Fail("wrong type!") 52 | } 53 | }) 54 | 55 | It("returns a RemoveIPAliasCommand", func() { 56 | message := bytes.NewReader([]byte{uint8(2)}) 57 | 58 | command, err := cmd.UnmarshalCommand(message) 59 | 60 | Expect(err).NotTo(HaveOccurred()) 61 | switch command.(type) { 62 | case *cmd.RemoveIPAliasCommand: 63 | default: 64 | Fail("wrong type!") 65 | } 66 | }) 67 | 68 | It("returns a AddIPAliasCommand", func() { 69 | message := bytes.NewReader([]byte{uint8(3)}) 70 | 71 | command, err := cmd.UnmarshalCommand(message) 72 | 73 | Expect(err).NotTo(HaveOccurred()) 74 | switch command.(type) { 75 | case *cmd.AddIPAliasCommand: 76 | default: 77 | Fail("wrong type!") 78 | } 79 | }) 80 | }) 81 | -------------------------------------------------------------------------------- /scripts/run-docker-tests.ps1: -------------------------------------------------------------------------------- 1 | param ( 2 | [Parameter(Mandatory=$true)] 3 | $p 4 | ) 5 | 6 | $domain="dev.cfdev.sh" 7 | $cats_path=$p 8 | 9 | $env:CONFIG="$env:TEMP\config.json" 10 | $REGISTRY_AUTH_FILE="$env:TEMP\registry.auth" 11 | 12 | Set-Content -Path $REGISTRY_AUTH_FILE -Value 'testuser:$2y$05$AgAP8TfkxY4Fl/R7y0DOu.Ex4KGXZaHoeT2VTnFudmYoG80YGZHR.' 13 | 14 | docker rm -f registry-cfdev 15 | 16 | docker run -d -p 5000:5000 --restart always --name registry-cfdev -e REGISTRY_AUTH=htpasswd -e REGISTRY_AUTH_HTPASSWD_REALM=realm -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -v $REGISTRY_AUTH_FILE\:/auth/htpasswd registry:2 17 | 18 | docker pull cloudfoundry/diego-docker-app-custom:latest 19 | docker tag cloudfoundry/diego-docker-app-custom:latest localhost:5000/diego-docker-app-custom 20 | docker login localhost:5000 -u testuser -p testpassword 21 | docker push localhost:5000/diego-docker-app-custom 22 | 23 | @" 24 | { 25 | "api": "api.$domain", 26 | "apps_domain": "$domain", 27 | "admin_user": "admin", 28 | "admin_password": "admin", 29 | "admin_secret": "admin-client-secret", 30 | "skip_ssl_validation": true, 31 | "use_http": true, 32 | "use_log_cache": false, 33 | "backend": "diego", 34 | "include_apps": false, 35 | "include_detect": false, 36 | "include_persistent_app": false, 37 | "include_routing": false, 38 | "include_v3": false, 39 | "include_capi_no_bridge": false, 40 | "include_docker": true, 41 | "include_private_docker_registry": true, 42 | "private_docker_registry_image": "host.cfdev.sh:5000/diego-docker-app-custom", 43 | "private_docker_registry_username": "testuser", 44 | "private_docker_registry_password": "testpassword", 45 | "default_timeout": 120, 46 | "cf_push_timeout": 120, 47 | "long_curl_timeout": 120, 48 | "broker_start_timeout": 120, 49 | "async_service_operation_timeout": 120, 50 | "sleep_timeout": 60 51 | } 52 | "@ | Set-Content -Path $env:CONFIG 53 | 54 | Push-Location "$cats_path" 55 | ginkgo -slowSpecThreshold=1200 -flakeAttempts=3 -noisyPendings=false -noisySkippings=false . 56 | if ($LASTEXITCODE -ne 0) { Exit $LASTEXITCODE } 57 | Pop-Location -------------------------------------------------------------------------------- /cmd/stop/mocks/cfdevd_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/stop (interfaces: CfdevdClient) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockCfdevdClient is a mock of CfdevdClient interface 13 | type MockCfdevdClient struct { 14 | ctrl *gomock.Controller 15 | recorder *MockCfdevdClientMockRecorder 16 | } 17 | 18 | // MockCfdevdClientMockRecorder is the mock recorder for MockCfdevdClient 19 | type MockCfdevdClientMockRecorder struct { 20 | mock *MockCfdevdClient 21 | } 22 | 23 | // NewMockCfdevdClient creates a new mock instance 24 | func NewMockCfdevdClient(ctrl *gomock.Controller) *MockCfdevdClient { 25 | mock := &MockCfdevdClient{ctrl: ctrl} 26 | mock.recorder = &MockCfdevdClientMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockCfdevdClient) EXPECT() *MockCfdevdClientMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // RemoveIPAlias mocks base method 36 | func (m *MockCfdevdClient) RemoveIPAlias() (string, error) { 37 | ret := m.ctrl.Call(m, "RemoveIPAlias") 38 | ret0, _ := ret[0].(string) 39 | ret1, _ := ret[1].(error) 40 | return ret0, ret1 41 | } 42 | 43 | // RemoveIPAlias indicates an expected call of RemoveIPAlias 44 | func (mr *MockCfdevdClientMockRecorder) RemoveIPAlias() *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveIPAlias", reflect.TypeOf((*MockCfdevdClient)(nil).RemoveIPAlias)) 46 | } 47 | 48 | // Uninstall mocks base method 49 | func (m *MockCfdevdClient) Uninstall() (string, error) { 50 | ret := m.ctrl.Call(m, "Uninstall") 51 | ret0, _ := ret[0].(string) 52 | ret1, _ := ret[1].(error) 53 | return ret0, ret1 54 | } 55 | 56 | // Uninstall indicates an expected call of Uninstall 57 | func (mr *MockCfdevdClientMockRecorder) Uninstall() *gomock.Call { 58 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Uninstall", reflect.TypeOf((*MockCfdevdClient)(nil).Uninstall)) 59 | } 60 | -------------------------------------------------------------------------------- /acceptance/acceptance_suite_test.go: -------------------------------------------------------------------------------- 1 | package acceptance 2 | 3 | import ( 4 | "io/ioutil" 5 | "os/exec" 6 | "path/filepath" 7 | "runtime" 8 | "testing" 9 | "time" 10 | 11 | "github.com/cloudfoundry-incubator/cf-test-helpers/cf" 12 | . "github.com/onsi/ginkgo" 13 | . "github.com/onsi/gomega" 14 | 15 | "os" 16 | 17 | "github.com/onsi/gomega/gexec" 18 | ) 19 | 20 | var ( 21 | pluginPath string 22 | tmpDir, cfHome, cfdevHome string 23 | cfPluginHome string 24 | ) 25 | 26 | func TestCFDev(t *testing.T) { 27 | RegisterFailHandler(Fail) 28 | RunSpecs(t, "cf dev - acceptance suite") 29 | } 30 | 31 | var _ = BeforeSuite(func() { 32 | SetDefaultEventuallyTimeout(time.Minute) 33 | 34 | pluginPath = os.Getenv("CFDEV_PLUGIN_PATH") 35 | if pluginPath == "" { 36 | Fail("Please set CFDEV_PLUGIN_PATH env var to a fully qualified path to a valid plugin") 37 | } 38 | 39 | var err error 40 | cfPluginHome, err = ioutil.TempDir("", "cfdev-plugin-") 41 | Expect(err).ToNot(HaveOccurred()) 42 | os.Setenv("CF_PLUGIN_HOME", cfPluginHome) 43 | 44 | session := cf.Cf("install-plugin", pluginPath, "-f") 45 | Eventually(session).Should(gexec.Exit()) 46 | }) 47 | 48 | var _ = AfterSuite(func() { 49 | cf.Cf("uninstall-plugin", "cfdev") 50 | os.Unsetenv("CF_PLUGIN_HOME") 51 | }) 52 | 53 | var _ = BeforeEach(func() { 54 | var err error 55 | tmpDir, err = ioutil.TempDir("", "cfdev-acceptance-") 56 | Expect(err).ToNot(HaveOccurred()) 57 | 58 | cfHome = filepath.Join(tmpDir, "cf_home") 59 | Expect(os.Mkdir(cfHome, 0755)).To(Succeed()) 60 | os.Setenv("CF_HOME", cfHome) 61 | 62 | cfdevHome = filepath.Join(tmpDir, "cfdev_home") 63 | Expect(os.Mkdir(cfdevHome, 0755)).To(Succeed()) 64 | os.Setenv("CFDEV_HOME", cfdevHome) 65 | }) 66 | 67 | var _ = AfterEach(func() { 68 | session := cf.Cf("dev", "stop") 69 | Eventually(session).Should(gexec.Exit()) 70 | 71 | if runtime.GOOS == "windows" { 72 | exec.Command("powershell.exe", "-Command", "Stop-Process -Name cfdev,cf -Force -EA 0").Run() 73 | } 74 | 75 | Expect(os.RemoveAll(tmpDir)).To(Succeed()) 76 | os.Unsetenv("CF_HOME") 77 | os.Unsetenv("CFDEV_HOME") 78 | }) 79 | -------------------------------------------------------------------------------- /driver/hyperkit/safekill_darwin_test.go: -------------------------------------------------------------------------------- 1 | package hyperkit_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/driver/hyperkit" 5 | "io/ioutil" 6 | "os" 7 | "os/exec" 8 | "path/filepath" 9 | "strconv" 10 | 11 | "github.com/onsi/gomega/gexec" 12 | 13 | . "github.com/onsi/ginkgo" 14 | . "github.com/onsi/gomega" 15 | ) 16 | 17 | var _ = Describe("safe kill test", func() { 18 | var ( 19 | err error 20 | processToKill *gexec.Session 21 | tmpDir string 22 | pidFile string 23 | ) 24 | 25 | BeforeEach(func() { 26 | tmpDir, err = ioutil.TempDir(os.Getenv("TMPDIR"), "safe-kill-test") 27 | Expect(err).NotTo(HaveOccurred()) 28 | processToKill, err = gexec.Start(exec.Command("sleep", "36000"), GinkgoWriter, GinkgoWriter) 29 | Expect(err).NotTo(HaveOccurred()) 30 | pidFile = filepath.Join(tmpDir, "processToKill.pid") 31 | ioutil.WriteFile( 32 | pidFile, 33 | []byte(strconv.Itoa(processToKill.Command.Process.Pid)), 34 | 0644, 35 | ) 36 | }) 37 | 38 | AfterEach(func() { 39 | Expect(os.RemoveAll(tmpDir)).To(Succeed()) 40 | gexec.KillAndWait() 41 | }) 42 | 43 | Context("process is still running", func() { 44 | It("kills the process and clean up the pidfile", func() { 45 | Expect(hyperkit.SafeKill(pidFile, "sleep")).To(Succeed()) 46 | Eventually(processToKill).Should(gexec.Exit()) 47 | Expect(pidFile).NotTo(BeAnExistingFile()) 48 | }) 49 | }) 50 | 51 | Context("process is still running with different filename", func() { 52 | It("leaves process running and cleans up the pidfile", func() { 53 | Expect(hyperkit.SafeKill(pidFile, "other")).To(Succeed()) 54 | Expect(pidFile).NotTo(BeAnExistingFile()) 55 | Expect(processToKill).ShouldNot(gexec.Exit()) 56 | }) 57 | }) 58 | 59 | Context("process is no longer running", func() { 60 | BeforeEach(func() { 61 | gexec.KillAndWait() 62 | Expect(processToKill).To(gexec.Exit()) 63 | }) 64 | 65 | It("cleans up the pidfile", func() { 66 | Expect(hyperkit.SafeKill(pidFile, "sleep")).To(Succeed()) 67 | Eventually(processToKill).Should(gexec.Exit()) 68 | Expect(pidFile).NotTo(BeAnExistingFile()) 69 | }) 70 | }) 71 | }) 72 | -------------------------------------------------------------------------------- /config/proxy_test.go: -------------------------------------------------------------------------------- 1 | package config_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/config" 5 | . "github.com/onsi/ginkgo" 6 | . "github.com/onsi/gomega" 7 | "os" 8 | ) 9 | 10 | var _ = Describe("BuildProxyConfig", func() { 11 | var ( 12 | cfg = config.Config{ 13 | BoshDirectorIP: "bosh-ip", 14 | CFRouterIP: "router-ip", 15 | HostIP: "host-ip", 16 | } 17 | ) 18 | 19 | Context("when proxy env vars are set", func() { 20 | BeforeEach(func() { 21 | os.Setenv("HTTP_PROXY", "some-http-proxy") 22 | os.Setenv("HTTPS_PROXY", "some-https-proxy") 23 | os.Setenv("NO_PROXY", "some-no-proxy") 24 | }) 25 | 26 | AfterEach(func() { 27 | os.Unsetenv("HTTP_PROXY") 28 | os.Unsetenv("HTTPS_PROXY") 29 | os.Unsetenv("NO_PROXY") 30 | }) 31 | 32 | It("returns the http config", func() { 33 | proxyConfig := cfg.BuildProxyConfig() 34 | Expect(proxyConfig.Http).To(Equal("some-http-proxy")) 35 | Expect(proxyConfig.Https).To(Equal("some-https-proxy")) 36 | Expect(proxyConfig.NoProxy).To(Equal("some-no-proxy,bosh-ip,router-ip,host-ip")) 37 | }) 38 | }) 39 | 40 | Context("when multiple mixed case proxy envs prioritize uppercase", func() { 41 | BeforeEach(func() { 42 | os.Setenv("http_proxy", "lower-case-http-proxy") 43 | os.Setenv("HTTP_PROXY", "upper-some-http-proxy") 44 | os.Setenv("https_proxy", "lower-case-https-proxy") 45 | os.Setenv("HTTPS_PROXY", "upper-some-https-proxy") 46 | os.Setenv("no_proxy", "lower-some-no-proxy") 47 | os.Setenv("NO_PROXY", "upper-some-no-proxy,bosh-ip,router-ip") 48 | }) 49 | 50 | AfterEach(func() { 51 | os.Unsetenv("http_proxy") 52 | os.Unsetenv("HTTP_PROXY") 53 | os.Unsetenv("https_proxy") 54 | os.Unsetenv("HTTPS_PROXY") 55 | os.Unsetenv("no_proxy") 56 | os.Unsetenv("NO_PROXY") 57 | }) 58 | 59 | It("returns the http config", func() { 60 | proxyConfig := cfg.BuildProxyConfig() 61 | Expect(proxyConfig.Http).To(Equal("upper-some-http-proxy")) 62 | Expect(proxyConfig.Https).To(Equal("upper-some-https-proxy")) 63 | Expect(proxyConfig.NoProxy).To(Equal("upper-some-no-proxy,bosh-ip,router-ip,host-ip")) 64 | }) 65 | }) 66 | }) 67 | -------------------------------------------------------------------------------- /cmd/start/mocks/vpnkit.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: VpnKit) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockVpnKit is a mock of VpnKit interface 13 | type MockVpnKit struct { 14 | ctrl *gomock.Controller 15 | recorder *MockVpnKitMockRecorder 16 | } 17 | 18 | // MockVpnKitMockRecorder is the mock recorder for MockVpnKit 19 | type MockVpnKitMockRecorder struct { 20 | mock *MockVpnKit 21 | } 22 | 23 | // NewMockVpnKit creates a new mock instance 24 | func NewMockVpnKit(ctrl *gomock.Controller) *MockVpnKit { 25 | mock := &MockVpnKit{ctrl: ctrl} 26 | mock.recorder = &MockVpnKitMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockVpnKit) EXPECT() *MockVpnKitMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Start mocks base method 36 | func (m *MockVpnKit) Start() error { 37 | ret := m.ctrl.Call(m, "Start") 38 | ret0, _ := ret[0].(error) 39 | return ret0 40 | } 41 | 42 | // Start indicates an expected call of Start 43 | func (mr *MockVpnKitMockRecorder) Start() *gomock.Call { 44 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockVpnKit)(nil).Start)) 45 | } 46 | 47 | // Stop mocks base method 48 | func (m *MockVpnKit) Stop() error { 49 | ret := m.ctrl.Call(m, "Stop") 50 | ret0, _ := ret[0].(error) 51 | return ret0 52 | } 53 | 54 | // Stop indicates an expected call of Stop 55 | func (mr *MockVpnKitMockRecorder) Stop() *gomock.Call { 56 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockVpnKit)(nil).Stop)) 57 | } 58 | 59 | // Watch mocks base method 60 | func (m *MockVpnKit) Watch(arg0 chan string) { 61 | m.ctrl.Call(m, "Watch", arg0) 62 | } 63 | 64 | // Watch indicates an expected call of Watch 65 | func (mr *MockVpnKitMockRecorder) Watch(arg0 interface{}) *gomock.Call { 66 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Watch", reflect.TypeOf((*MockVpnKit)(nil).Watch), arg0) 67 | } 68 | -------------------------------------------------------------------------------- /cmd/start/mocks/system-profiler.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: SystemProfiler) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockSystemProfiler is a mock of SystemProfiler interface 13 | type MockSystemProfiler struct { 14 | ctrl *gomock.Controller 15 | recorder *MockSystemProfilerMockRecorder 16 | } 17 | 18 | // MockSystemProfilerMockRecorder is the mock recorder for MockSystemProfiler 19 | type MockSystemProfilerMockRecorder struct { 20 | mock *MockSystemProfiler 21 | } 22 | 23 | // NewMockSystemProfiler creates a new mock instance 24 | func NewMockSystemProfiler(ctrl *gomock.Controller) *MockSystemProfiler { 25 | mock := &MockSystemProfiler{ctrl: ctrl} 26 | mock.recorder = &MockSystemProfilerMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockSystemProfiler) EXPECT() *MockSystemProfilerMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // GetAvailableMemory mocks base method 36 | func (m *MockSystemProfiler) GetAvailableMemory() (uint64, error) { 37 | ret := m.ctrl.Call(m, "GetAvailableMemory") 38 | ret0, _ := ret[0].(uint64) 39 | ret1, _ := ret[1].(error) 40 | return ret0, ret1 41 | } 42 | 43 | // GetAvailableMemory indicates an expected call of GetAvailableMemory 44 | func (mr *MockSystemProfilerMockRecorder) GetAvailableMemory() *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAvailableMemory", reflect.TypeOf((*MockSystemProfiler)(nil).GetAvailableMemory)) 46 | } 47 | 48 | // GetTotalMemory mocks base method 49 | func (m *MockSystemProfiler) GetTotalMemory() (uint64, error) { 50 | ret := m.ctrl.Call(m, "GetTotalMemory") 51 | ret0, _ := ret[0].(uint64) 52 | ret1, _ := ret[1].(error) 53 | return ret0, ret1 54 | } 55 | 56 | // GetTotalMemory indicates an expected call of GetTotalMemory 57 | func (mr *MockSystemProfilerMockRecorder) GetTotalMemory() *gomock.Call { 58 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTotalMemory", reflect.TypeOf((*MockSystemProfiler)(nil).GetTotalMemory)) 59 | } 60 | -------------------------------------------------------------------------------- /pkg/analyticsd/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "crypto/tls" 6 | "fmt" 7 | "gopkg.in/segmentio/analytics-go.v3" 8 | "net/http" 9 | "os" 10 | "os/signal" 11 | "syscall" 12 | "time" 13 | 14 | cfdevos "code.cloudfoundry.org/cfdev/os" 15 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/daemon" 16 | "github.com/denisbrodbeck/machineid" 17 | "golang.org/x/oauth2" 18 | "golang.org/x/oauth2/clientcredentials" 19 | ) 20 | 21 | var ( 22 | analyticsKey string 23 | testAnalyticsKey string 24 | version string 25 | pollingInterval = 10 * time.Minute 26 | ) 27 | 28 | func main() { 29 | cfg := &clientcredentials.Config{ 30 | ClientID: "analytics", 31 | ClientSecret: "analytics", 32 | TokenURL: "https://uaa.dev.cfdev.sh/oauth/token", 33 | } 34 | 35 | httpClient := &http.Client{ 36 | Timeout: 10 * time.Second, 37 | Transport: &http.Transport{ 38 | TLSClientConfig: &tls.Config{ 39 | InsecureSkipVerify: true, 40 | }, 41 | }, 42 | } 43 | 44 | ctx := context.Background() 45 | ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient) 46 | 47 | userID, err := machineid.ProtectedID("cfdev") 48 | if err != nil { 49 | userID = "UNKNOWN_ID" 50 | } 51 | 52 | o := cfdevos.OS{} 53 | osVersion, err := o.Version() 54 | if err != nil { 55 | osVersion = "unknown-os-version" 56 | } 57 | 58 | if os.Getenv("CFDEV_MODE") == "debug" { 59 | pollingInterval = 10 * time.Second 60 | } 61 | 62 | var analytixKey string 63 | if os.Getenv("CFDEV_MODE") == "debug" || analyticsKey == "" { 64 | analytixKey = testAnalyticsKey 65 | } else { 66 | analytixKey = analyticsKey 67 | } 68 | 69 | analyticsDaemon := daemon.New( 70 | "https://api.dev.cfdev.sh", 71 | userID, 72 | version, 73 | osVersion, 74 | os.Stdout, 75 | cfg.Client(ctx), 76 | analytics.New(analytixKey), 77 | pollingInterval, 78 | ) 79 | 80 | sigs := make(chan os.Signal, 1) 81 | signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) 82 | go func() { 83 | <-sigs 84 | analyticsDaemon.Stop() 85 | }() 86 | 87 | fmt.Printf("[ANALYTICSD] apiKeyLoaded: %t, pollingInterval: %v, version: %q, time: %v, userID: %q\n", 88 | analyticsKey != "", pollingInterval, version, time.Now(), userID) 89 | analyticsDaemon.Start() 90 | } 91 | -------------------------------------------------------------------------------- /scripts/meow.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [[ -z "$1" ]]; then 6 | echo "USAGE: $0 " 7 | exit 1 8 | fi 9 | 10 | domain=dev.cfdev.sh 11 | cats_path=$1 12 | 13 | function run_cats() { 14 | export CONFIG=$(mktemp -t config.XXXXXXXX) 15 | cat <${CONFIG} 16 | { 17 | "api": "api.$domain", 18 | "apps_domain": "$domain", 19 | "admin_user": "admin", 20 | "admin_password": "admin", 21 | "admin_secret": "admin-client-secret", 22 | "skip_ssl_validation": true, 23 | "stacks": ["cflinuxfs3"], 24 | "use_http": true, 25 | "use_log_cache": false, 26 | "backend": "diego", 27 | "include_apps": true, 28 | "include_backend_compatibility": false, 29 | "include_container_networking": ${INCLUDE_CONTAINER_NETWORKING:-true}, 30 | "include_capi_no_bridge" : true, 31 | "include_detect": true, 32 | "include_docker": true, 33 | "include_internet_dependent": true, 34 | "include_persistent_app": true, 35 | "include_privileged_container_support": false, 36 | "include_route_services": false, 37 | "include_routing": true, 38 | "include_security_groups": true, 39 | "include_services": true, 40 | "include_ssh": true, 41 | "include_sso": true, 42 | "include_tasks": true, 43 | "include_v3": true, 44 | "java_buildpack_name": "${JAVA_BUILDPACK_NAME:-java_buildpack}", 45 | "default_timeout": 120, 46 | "cf_push_timeout": 120, 47 | "long_curl_timeout": 120, 48 | "broker_start_timeout": 120, 49 | "async_service_operation_timeout": 120, 50 | "sleep_timeout": 60 51 | } 52 | EOF 53 | 54 | pushd ${cats_path} >/dev/null 55 | ./bin/test -slowSpecThreshold=1200 --flakeAttempts=3 ${@:2} . 56 | popd >/dev/null 57 | 58 | } 59 | 60 | # Remove PCF Dev 'all_access' application security group 61 | export CF_HOME=$(mktemp -d) 62 | cf api api.$domain --skip-ssl-validation 63 | cf auth admin admin 64 | 65 | cf unbind-staging-security-group all_access 66 | cf unbind-running-security-group all_access 67 | 68 | run_cats $@ 69 | 70 | # Re-enable PCF Dev 'all_access' application security group 71 | export CF_HOME=$(mktemp -d) 72 | cf api api.$domain --skip-ssl-validation 73 | cf auth admin admin 74 | 75 | cf bind-staging-security-group all_access 76 | cf bind-running-security-group all_access 77 | -------------------------------------------------------------------------------- /acceptance/privileged/privileged_suite_test.go: -------------------------------------------------------------------------------- 1 | package privileged_test 2 | 3 | import ( 4 | . "code.cloudfoundry.org/cfdev/acceptance" 5 | "encoding/json" 6 | "fmt" 7 | "github.com/cloudfoundry-incubator/cf-test-helpers/cf" 8 | . "github.com/onsi/ginkgo" 9 | . "github.com/onsi/gomega" 10 | "io/ioutil" 11 | "os" 12 | "testing" 13 | "time" 14 | ) 15 | 16 | type config struct { 17 | AwsAccessKeyID string `json:"aws_access_key_id"` 18 | AwsSecretAccessKey string `json:"aws_secret_access_key"` 19 | StartUp bool `json:"start_up"` 20 | CleanUp bool `json:"clean_up"` 21 | TarballPath string `json:"tarball_path"` 22 | PluginPath string `json:"plugin_path"` 23 | 24 | MysqlService string `json:"service"` 25 | MysqlServicePlan string `json:"service_plan"` 26 | } 27 | 28 | var cfg = config{ 29 | StartUp: true, 30 | CleanUp: true, 31 | MysqlService: "p-mysql", 32 | MysqlServicePlan: "10mb", 33 | } 34 | 35 | func TestPrivileged(t *testing.T) { 36 | RegisterFailHandler(Fail) 37 | RunSpecs(t, "cf dev - acceptance - privileged suite") 38 | } 39 | 40 | var _ = BeforeSuite(func() { 41 | SetDefaultEventuallyTimeout(5 * time.Minute) 42 | 43 | Expect(HasSudoPrivilege()).To(BeTrue(), "Please run 'sudo echo hi' first") 44 | 45 | if path := os.Getenv("CFDEV_ACCEPTANCE_CONFIG"); path != "" { 46 | contents, err := ioutil.ReadFile(path) 47 | if err != nil { 48 | Fail(fmt.Sprintf("failed to read acceptance config file at: %s", path)) 49 | } 50 | 51 | err = json.Unmarshal([]byte(contents), &cfg) 52 | if err != nil { 53 | Fail(fmt.Sprintf("Unable to parse 'CFDEV_ACCEPTANCE_CONFIG'. Please make sure that the env var is valid json: %s", contents)) 54 | } 55 | } 56 | 57 | if cfg.PluginPath != "" { 58 | session := cf.Cf("install-plugin", "-f", cfg.PluginPath) 59 | <-session.Exited 60 | } else { 61 | fmt.Fprintln(GinkgoWriter, "WARNING plugin_path omitted as part of 'CFDEV_ACCEPTANCE_CONFIG'. Skipping plugin installation...") 62 | } 63 | 64 | os.Setenv("CFDEV_MODE", "debug") 65 | os.Setenv("CF_COLOR", "false") 66 | os.Unsetenv("BOSH_ALL_PROXY") 67 | }) 68 | 69 | var _ = AfterSuite(func() { 70 | os.Unsetenv("CF_COLOR") 71 | os.Unsetenv("CFDEV_MODE") 72 | 73 | if cfg.PluginPath != "" { 74 | cf.Cf("uninstall-plugin", "cfdev") 75 | } 76 | }) 77 | -------------------------------------------------------------------------------- /driver/hyperv/requirements.go: -------------------------------------------------------------------------------- 1 | package hyperv 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "errors" 7 | 8 | safeerr "code.cloudfoundry.org/cfdev/errors" 9 | ) 10 | 11 | const ( 12 | admin_role = "[Security.Principal.WindowsBuiltInRole]::Administrator" 13 | current_user = "New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())" 14 | hyperv_disabled_error = `You must first enable Hyper-V on your machine before you run CF Dev. Please use the following tutorial to enable this functionality on your machine 15 | 16 | https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v` 17 | ) 18 | 19 | func (d *HyperV) hasAdminPrivileged() error { 20 | command := fmt.Sprintf("(%s).IsInRole(%s)", current_user, admin_role) 21 | 22 | output, err := d.Powershell.Output(command) 23 | if err != nil { 24 | return fmt.Errorf("checking for admin privileges: %s", err) 25 | } 26 | 27 | if strings.Contains(strings.ToLower(output), "true") { 28 | return nil 29 | } 30 | 31 | return safeerr.SafeWrap(errors.New("You must run cf dev with an admin privileged powershell"), "Running without admin privileges") 32 | } 33 | 34 | func (d *HyperV) hypervEnabled() error { 35 | // The Microsoft-Hyper-V and the Microsoft-Hyper-V-Management-PowerShell are required. 36 | status, err := d.hypervStatus("Microsoft-Hyper-V") 37 | if err != nil { 38 | return err 39 | } 40 | 41 | if !strings.Contains(strings.ToLower(status), "enabled") { 42 | return safeerr.SafeWrap(errors.New(hyperv_disabled_error), "Microsoft-Hyper-V disabled") 43 | } 44 | 45 | status, err = d.hypervStatus("Microsoft-Hyper-V-Management-PowerShell") 46 | if err != nil { 47 | return err 48 | } 49 | 50 | if !strings.Contains(strings.ToLower(status), "enabled") { 51 | return safeerr.SafeWrap(errors.New(hyperv_disabled_error), "Microsoft-Hyper-V-Management-PowerShell disabled") 52 | } 53 | 54 | return nil 55 | } 56 | 57 | func (d *HyperV) hypervStatus(featureName string) (string, error) { 58 | command := fmt.Sprintf("(Get-WindowsOptionalFeature -FeatureName %s -Online).State", featureName) 59 | 60 | output, err := d.Powershell.Output(command) 61 | if err != nil { 62 | return "", fmt.Errorf("checking whether hyperv is enabled: %s", err) 63 | } 64 | 65 | return strings.TrimSpace(output), nil 66 | } 67 | -------------------------------------------------------------------------------- /cmd/start/mocks/analyticsd.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: AnalyticsD) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockAnalyticsD is a mock of AnalyticsD interface 13 | type MockAnalyticsD struct { 14 | ctrl *gomock.Controller 15 | recorder *MockAnalyticsDMockRecorder 16 | } 17 | 18 | // MockAnalyticsDMockRecorder is the mock recorder for MockAnalyticsD 19 | type MockAnalyticsDMockRecorder struct { 20 | mock *MockAnalyticsD 21 | } 22 | 23 | // NewMockAnalyticsD creates a new mock instance 24 | func NewMockAnalyticsD(ctrl *gomock.Controller) *MockAnalyticsD { 25 | mock := &MockAnalyticsD{ctrl: ctrl} 26 | mock.recorder = &MockAnalyticsDMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockAnalyticsD) EXPECT() *MockAnalyticsDMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // IsRunning mocks base method 36 | func (m *MockAnalyticsD) IsRunning() (bool, error) { 37 | ret := m.ctrl.Call(m, "IsRunning") 38 | ret0, _ := ret[0].(bool) 39 | ret1, _ := ret[1].(error) 40 | return ret0, ret1 41 | } 42 | 43 | // IsRunning indicates an expected call of IsRunning 44 | func (mr *MockAnalyticsDMockRecorder) IsRunning() *gomock.Call { 45 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsRunning", reflect.TypeOf((*MockAnalyticsD)(nil).IsRunning)) 46 | } 47 | 48 | // Start mocks base method 49 | func (m *MockAnalyticsD) Start() error { 50 | ret := m.ctrl.Call(m, "Start") 51 | ret0, _ := ret[0].(error) 52 | return ret0 53 | } 54 | 55 | // Start indicates an expected call of Start 56 | func (mr *MockAnalyticsDMockRecorder) Start() *gomock.Call { 57 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Start", reflect.TypeOf((*MockAnalyticsD)(nil).Start)) 58 | } 59 | 60 | // Stop mocks base method 61 | func (m *MockAnalyticsD) Stop() error { 62 | ret := m.ctrl.Call(m, "Stop") 63 | ret0, _ := ret[0].(error) 64 | return ret0 65 | } 66 | 67 | // Stop indicates an expected call of Stop 68 | func (mr *MockAnalyticsDMockRecorder) Stop() *gomock.Call { 69 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stop", reflect.TypeOf((*MockAnalyticsD)(nil).Stop)) 70 | } 71 | -------------------------------------------------------------------------------- /cmd/bosh/mocks/analytics_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/bosh (interfaces: AnalyticsClient) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockAnalyticsClient is a mock of AnalyticsClient interface 13 | type MockAnalyticsClient struct { 14 | ctrl *gomock.Controller 15 | recorder *MockAnalyticsClientMockRecorder 16 | } 17 | 18 | // MockAnalyticsClientMockRecorder is the mock recorder for MockAnalyticsClient 19 | type MockAnalyticsClientMockRecorder struct { 20 | mock *MockAnalyticsClient 21 | } 22 | 23 | // NewMockAnalyticsClient creates a new mock instance 24 | func NewMockAnalyticsClient(ctrl *gomock.Controller) *MockAnalyticsClient { 25 | mock := &MockAnalyticsClient{ctrl: ctrl} 26 | mock.recorder = &MockAnalyticsClientMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockAnalyticsClient) EXPECT() *MockAnalyticsClientMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Event mocks base method 36 | func (m *MockAnalyticsClient) Event(arg0 string, arg1 ...map[string]interface{}) error { 37 | varargs := []interface{}{arg0} 38 | for _, a := range arg1 { 39 | varargs = append(varargs, a) 40 | } 41 | ret := m.ctrl.Call(m, "Event", varargs...) 42 | ret0, _ := ret[0].(error) 43 | return ret0 44 | } 45 | 46 | // Event indicates an expected call of Event 47 | func (mr *MockAnalyticsClientMockRecorder) Event(arg0 interface{}, arg1 ...interface{}) *gomock.Call { 48 | varargs := append([]interface{}{arg0}, arg1...) 49 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Event", reflect.TypeOf((*MockAnalyticsClient)(nil).Event), varargs...) 50 | } 51 | 52 | // PromptOptInIfNeeded mocks base method 53 | func (m *MockAnalyticsClient) PromptOptInIfNeeded(arg0 string) error { 54 | ret := m.ctrl.Call(m, "PromptOptInIfNeeded", arg0) 55 | ret0, _ := ret[0].(error) 56 | return ret0 57 | } 58 | 59 | // PromptOptInIfNeeded indicates an expected call of PromptOptInIfNeeded 60 | func (mr *MockAnalyticsClientMockRecorder) PromptOptInIfNeeded(arg0 interface{}) *gomock.Call { 61 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PromptOptInIfNeeded", reflect.TypeOf((*MockAnalyticsClient)(nil).PromptOptInIfNeeded), arg0) 62 | } 63 | -------------------------------------------------------------------------------- /cmd/start/mocks/analytics_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by MockGen. DO NOT EDIT. 2 | // Source: code.cloudfoundry.org/cfdev/cmd/start (interfaces: AnalyticsClient) 3 | 4 | // Package mocks is a generated GoMock package. 5 | package mocks 6 | 7 | import ( 8 | gomock "github.com/golang/mock/gomock" 9 | reflect "reflect" 10 | ) 11 | 12 | // MockAnalyticsClient is a mock of AnalyticsClient interface 13 | type MockAnalyticsClient struct { 14 | ctrl *gomock.Controller 15 | recorder *MockAnalyticsClientMockRecorder 16 | } 17 | 18 | // MockAnalyticsClientMockRecorder is the mock recorder for MockAnalyticsClient 19 | type MockAnalyticsClientMockRecorder struct { 20 | mock *MockAnalyticsClient 21 | } 22 | 23 | // NewMockAnalyticsClient creates a new mock instance 24 | func NewMockAnalyticsClient(ctrl *gomock.Controller) *MockAnalyticsClient { 25 | mock := &MockAnalyticsClient{ctrl: ctrl} 26 | mock.recorder = &MockAnalyticsClientMockRecorder{mock} 27 | return mock 28 | } 29 | 30 | // EXPECT returns an object that allows the caller to indicate expected use 31 | func (m *MockAnalyticsClient) EXPECT() *MockAnalyticsClientMockRecorder { 32 | return m.recorder 33 | } 34 | 35 | // Event mocks base method 36 | func (m *MockAnalyticsClient) Event(arg0 string, arg1 ...map[string]interface{}) error { 37 | varargs := []interface{}{arg0} 38 | for _, a := range arg1 { 39 | varargs = append(varargs, a) 40 | } 41 | ret := m.ctrl.Call(m, "Event", varargs...) 42 | ret0, _ := ret[0].(error) 43 | return ret0 44 | } 45 | 46 | // Event indicates an expected call of Event 47 | func (mr *MockAnalyticsClientMockRecorder) Event(arg0 interface{}, arg1 ...interface{}) *gomock.Call { 48 | varargs := append([]interface{}{arg0}, arg1...) 49 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Event", reflect.TypeOf((*MockAnalyticsClient)(nil).Event), varargs...) 50 | } 51 | 52 | // PromptOptInIfNeeded mocks base method 53 | func (m *MockAnalyticsClient) PromptOptInIfNeeded(arg0 string) error { 54 | ret := m.ctrl.Call(m, "PromptOptInIfNeeded", arg0) 55 | ret0, _ := ret[0].(error) 56 | return ret0 57 | } 58 | 59 | // PromptOptInIfNeeded indicates an expected call of PromptOptInIfNeeded 60 | func (mr *MockAnalyticsClientMockRecorder) PromptOptInIfNeeded(arg0 interface{}) *gomock.Call { 61 | return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PromptOptInIfNeeded", reflect.TypeOf((*MockAnalyticsClient)(nil).PromptOptInIfNeeded), arg0) 62 | } 63 | -------------------------------------------------------------------------------- /scripts/run-docker-tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | if [[ -z "$1" ]]; then 6 | echo "USAGE: $0 " 7 | exit 1 8 | fi 9 | 10 | domain=dev.cfdev.sh 11 | cats_path=$1 12 | 13 | function run_docker_registry_tests() { 14 | export CONFIG=$(mktemp -t config.XXXXXXXX) 15 | export REGISTRY_AUTH_FILE=$(mktemp /tmp/registry.auth.XXXXXXXX) 16 | 17 | # https://docs.docker.com/registry/deploying/#native-basic-auth 18 | # docker run \ 19 | # --entrypoint htpasswd \ 20 | # registry:2 -Bbn testuser testpassword > auth/htpasswd 21 | 22 | echo 'testuser:$2y$05$AgAP8TfkxY4Fl/R7y0DOu.Ex4KGXZaHoeT2VTnFudmYoG80YGZHR.' > ${REGISTRY_AUTH_FILE} 23 | 24 | docker rm -f registry-cfdev || true 25 | docker run -d -p 5000:5000 --restart always --name registry-cfdev \ 26 | -e REGISTRY_AUTH=htpasswd \ 27 | -e REGISTRY_AUTH_HTPASSWD_REALM=realm \ 28 | -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \ 29 | -v $REGISTRY_AUTH_FILE:/auth/htpasswd \ 30 | registry:2 31 | 32 | docker pull cloudfoundry/diego-docker-app-custom:latest 33 | docker tag cloudfoundry/diego-docker-app-custom:latest localhost:5000/diego-docker-app-custom 34 | docker login localhost:5000 -u testuser -p testpassword 35 | docker push localhost:5000/diego-docker-app-custom 36 | 37 | cat <${CONFIG} 38 | { 39 | "api": "api.$domain", 40 | "apps_domain": "$domain", 41 | "admin_user": "admin", 42 | "admin_password": "admin", 43 | "admin_secret": "admin-client-secret", 44 | "skip_ssl_validation": true, 45 | "use_http": true, 46 | "use_log_cache": false, 47 | "backend": "diego", 48 | "include_apps": false, 49 | "include_detect": false, 50 | "include_persistent_app": false, 51 | "include_routing": false, 52 | "include_v3": false, 53 | "include_capi_no_bridge": false, 54 | "include_docker": true, 55 | "include_private_docker_registry": true, 56 | "private_docker_registry_image": "host.cfdev.sh:5000/diego-docker-app-custom", 57 | "private_docker_registry_username": "testuser", 58 | "private_docker_registry_password": "testpassword", 59 | 60 | "default_timeout": 120, 61 | "cf_push_timeout": 120, 62 | "long_curl_timeout": 120, 63 | "broker_start_timeout": 120, 64 | "async_service_operation_timeout": 120, 65 | "sleep_timeout": 60 66 | } 67 | EOF 68 | 69 | pushd ${cats_path} >/dev/null 70 | ./bin/test -slowSpecThreshold=1200 -flakeAttempts=3 ${@:2} . 71 | popd >/dev/null 72 | } 73 | 74 | 75 | run_docker_registry_tests $@ -------------------------------------------------------------------------------- /pkg/analyticsd/command/app_create_test.go: -------------------------------------------------------------------------------- 1 | package command_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/command" 5 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment" 6 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/segment/mocks" 7 | "github.com/golang/mock/gomock" 8 | . "github.com/onsi/ginkgo" 9 | . "github.com/onsi/gomega" 10 | "gopkg.in/segmentio/analytics-go.v3" 11 | "io/ioutil" 12 | "log" 13 | "time" 14 | ) 15 | 16 | var _ = Describe("AppCreate", func() { 17 | var ( 18 | cmd *command.AppCreate 19 | mockController *gomock.Controller 20 | mockAnalytics *mocks.MockClient 21 | ) 22 | 23 | BeforeEach(func() { 24 | mockController = gomock.NewController(GinkgoT()) 25 | mockAnalytics = mocks.NewMockClient(mockController) 26 | segmentClient := segment.New( 27 | mockAnalytics, 28 | "some-user-uuid", 29 | "some-version", 30 | "some-os-version", 31 | time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC), 32 | ) 33 | 34 | cmd = &command.AppCreate{ 35 | Logger: log.New(ioutil.Discard, "", log.LstdFlags), 36 | AnalyticsClient: segmentClient, 37 | } 38 | }) 39 | 40 | AfterEach(func() { 41 | mockController.Finish() 42 | }) 43 | 44 | Context("when the buildpack is whitelisted", func() { 45 | It("sends the buildpack information to segment.io", func() { 46 | mockAnalytics.EXPECT().Enqueue(gomock.Any()).Do(func(event analytics.Track) { 47 | Expect(event.UserId).To(Equal("some-user-uuid")) 48 | Expect(event.Event).To(Equal("app created")) 49 | Expect(event.Timestamp).To(Equal(time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC))) 50 | Expect(event.Properties).To(HaveKeyWithValue("buildpack", "go")) 51 | }) 52 | 53 | body := []byte(` 54 | { 55 | "request": { 56 | "buildpack": "go_buildpack" 57 | } 58 | }`) 59 | 60 | cmd.HandleResponse(body) 61 | }) 62 | }) 63 | 64 | Context("when the buildpack is not whitelisted", func() { 65 | It("sends the buildpack information to segment.io", func() { 66 | mockAnalytics.EXPECT().Enqueue(gomock.Any()).Do(func(event analytics.Track) { 67 | Expect(event.UserId).To(Equal("some-user-uuid")) 68 | Expect(event.Event).To(Equal("app created")) 69 | Expect(event.Timestamp).To(Equal(time.Date(2018, 8, 8, 8, 8, 8, 0, time.UTC))) 70 | Expect(event.Properties).To(HaveKeyWithValue("buildpack", "custom")) 71 | }) 72 | 73 | body := []byte(` 74 | { 75 | "request": { 76 | "buildpack": "some-unexpected-buildpack" 77 | } 78 | }`) 79 | 80 | cmd.HandleResponse(body) 81 | }) 82 | }) 83 | }) 84 | -------------------------------------------------------------------------------- /cfanalytics/toggle/toggle.go: -------------------------------------------------------------------------------- 1 | package toggle 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "path/filepath" 9 | ) 10 | 11 | type Toggle struct { 12 | defined bool 13 | CfAnalyticsEnabled bool `json:"cfAnalyticsEnabled"` 14 | CustomAnalyticsEnabled bool `json:"customAnalyticsEnabled"` 15 | path string 16 | props map[string]interface{} 17 | } 18 | 19 | func New(path string) *Toggle { 20 | t := &Toggle{ 21 | defined: false, 22 | CfAnalyticsEnabled: false, 23 | CustomAnalyticsEnabled: false, 24 | path: path, 25 | props: make(map[string]interface{}, 1), 26 | } 27 | 28 | if txt, err := ioutil.ReadFile(path); err == nil { 29 | if err := json.Unmarshal(txt, &t); err == nil { 30 | t.path = path 31 | t.defined = true 32 | } else { 33 | fmt.Printf("Error unmarshalling json: %v", err) 34 | } 35 | } 36 | 37 | return t 38 | } 39 | 40 | func (t *Toggle) Defined() bool { 41 | return t.defined 42 | } 43 | 44 | func (t *Toggle) CustomAnalyticsDefined() bool { 45 | if !t.defined { 46 | return false 47 | } else { 48 | return !(t.CfAnalyticsEnabled && !t.CustomAnalyticsEnabled) 49 | } 50 | } 51 | 52 | func (t *Toggle) Enabled() bool { 53 | return t.CfAnalyticsEnabled || t.CustomAnalyticsEnabled 54 | } 55 | 56 | func (t *Toggle) IsCustom() bool { 57 | return t.CustomAnalyticsEnabled 58 | } 59 | 60 | func (t *Toggle) SetCFAnalyticsEnabled(value bool) error { 61 | t.defined = true 62 | if !value { 63 | t.CfAnalyticsEnabled = value 64 | t.CustomAnalyticsEnabled = value 65 | } else { 66 | t.CfAnalyticsEnabled = value 67 | } 68 | 69 | return t.save() 70 | } 71 | 72 | func (t *Toggle) SetCustomAnalyticsEnabled(value bool) error { 73 | t.defined = true 74 | t.CfAnalyticsEnabled = value 75 | t.CustomAnalyticsEnabled = value 76 | return t.save() 77 | } 78 | 79 | func (t *Toggle) GetProps() map[string]interface{} { 80 | return t.props 81 | } 82 | 83 | func (t *Toggle) SetProp(k, v string) error { 84 | t.props[k] = v 85 | return t.save() 86 | } 87 | 88 | func (t *Toggle) save() error { 89 | os.MkdirAll(filepath.Dir(t.path), 0755) 90 | hash := map[string]interface{}{"props": t.props} 91 | if t.defined { 92 | hash["cfAnalyticsEnabled"] = t.CfAnalyticsEnabled 93 | hash["customAnalyticsEnabled"] = t.CustomAnalyticsEnabled 94 | } 95 | txt, err := json.Marshal(hash) 96 | if err != nil { 97 | return err 98 | } 99 | return ioutil.WriteFile(t.path, txt, 0644) 100 | } 101 | -------------------------------------------------------------------------------- /pkg/cfdevd/client/client.go: -------------------------------------------------------------------------------- 1 | package client 2 | 3 | import ( 4 | "encoding/binary" 5 | "fmt" 6 | "net" 7 | "strings" 8 | 9 | "code.cloudfoundry.org/cfdev/errors" 10 | ) 11 | 12 | type Client struct { 13 | name [5]byte 14 | socket string 15 | } 16 | 17 | // clientName must be 5 characters 18 | func New(clientName, socketPath string) *Client { 19 | c := &Client{socket: socketPath} 20 | copy(c.name[:], clientName[:5]) 21 | return c 22 | } 23 | 24 | const eofReadingExitCodeMsg = "reading errorcode from cfdevd" 25 | const connectCfdevdMsg = "connecting to cfdevd" 26 | 27 | // sends command and returns serverName (and error) 28 | func (c *Client) Send(command uint8) (string, error) { 29 | handshake := append(c.name[:], make([]byte, 44, 44)...) 30 | conn, err := net.Dial("unix", c.socket) 31 | if err != nil { 32 | return "", errors.SafeWrap(err, connectCfdevdMsg) 33 | } 34 | defer conn.Close() 35 | 36 | if err := binary.Write(conn, binary.LittleEndian, handshake); err != nil { 37 | return "", errors.SafeWrap(err, "sending handshake to cfdevd") 38 | } 39 | 40 | if err := binary.Read(conn, binary.LittleEndian, handshake); err != nil { 41 | return "", errors.SafeWrap(err, "reading handshake from cfdevd") 42 | } 43 | 44 | serverName := string(handshake[:5]) 45 | if err := binary.Write(conn, binary.LittleEndian, []byte{command}); err != nil { 46 | return serverName, errors.SafeWrap(err, "sending command to cfdevd") 47 | } 48 | 49 | errorCode := make([]byte, 1, 1) 50 | if err := binary.Read(conn, binary.LittleEndian, errorCode); err != nil { 51 | return serverName, errors.SafeWrap(err, eofReadingExitCodeMsg) 52 | } else if errorCode[0] != 0 { 53 | return serverName, errors.SafeWrap(nil, fmt.Sprintf("failed to uninstall cfdevd: errorcode: %d", errorCode[0])) 54 | } 55 | return serverName, nil 56 | } 57 | 58 | func (c *Client) Uninstall() (string, error) { 59 | name, err := c.Send(1) 60 | if err != nil && (strings.HasPrefix(err.Error(), eofReadingExitCodeMsg) || strings.HasPrefix(err.Error(), connectCfdevdMsg)) { 61 | return name, nil 62 | } 63 | return name, err 64 | } 65 | 66 | func (c *Client) RemoveIPAlias() (string, error) { 67 | name, err := c.Send(2) 68 | if err != nil && (strings.HasPrefix(err.Error(), eofReadingExitCodeMsg) || strings.HasPrefix(err.Error(), connectCfdevdMsg)) { 69 | return name, nil 70 | } 71 | return name, err 72 | } 73 | 74 | func (c *Client) AddIPAlias() (string, error) { 75 | name, err := c.Send(3) 76 | if err != nil && (strings.HasPrefix(err.Error(), eofReadingExitCodeMsg) || strings.HasPrefix(err.Error(), connectCfdevdMsg)) { 77 | return name, nil 78 | } 79 | return name, err 80 | } 81 | -------------------------------------------------------------------------------- /pkg/servicew/program/program_test.go: -------------------------------------------------------------------------------- 1 | package program_test 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/servicew/config" 5 | . "github.com/onsi/ginkgo" 6 | . "github.com/onsi/gomega" 7 | "io/ioutil" 8 | "os" 9 | "os/exec" 10 | "path/filepath" 11 | "time" 12 | 13 | . "code.cloudfoundry.org/cfdev/pkg/servicew/program" 14 | ) 15 | 16 | var _ = Describe("Program", func() { 17 | var ( 18 | p *Program 19 | tempDir string 20 | ) 21 | 22 | BeforeEach(func() { 23 | tempDir = "" 24 | }) 25 | 26 | AfterEach(func() { 27 | // sleep just in case 28 | // to wait for process 29 | // to actually start 30 | time.Sleep(time.Second) 31 | p.Stop(nil) 32 | 33 | os.RemoveAll(tempDir) 34 | }) 35 | 36 | It("starts a process with a standard config", func() { 37 | var err error 38 | p, err = New(config.Config{ 39 | Label: "cfdev-program-test", 40 | Executable: "sleep", 41 | Args: []string{"1234"}, 42 | }) 43 | Expect(err).NotTo(HaveOccurred()) 44 | 45 | err = p.Start(nil) 46 | Expect(err).NotTo(HaveOccurred()) 47 | 48 | Eventually(func() string { 49 | output, _ := exec.Command("ps", "aux").Output() 50 | return string(output) 51 | }, 10*time.Second).Should(ContainSubstring("sleep 1234")) 52 | }) 53 | 54 | It("starts a process with environment variables", func() { 55 | var err error 56 | p, err = New(config.Config{ 57 | Label: "cfdev-program-test", 58 | Executable: "sh", 59 | Args: []string{"-c", "sleep $SLEEP_COUNT"}, 60 | Env: map[string]string{ 61 | "SLEEP_COUNT": "1235", 62 | }, 63 | }) 64 | Expect(err).NotTo(HaveOccurred()) 65 | 66 | err = p.Start(nil) 67 | Expect(err).NotTo(HaveOccurred()) 68 | 69 | Eventually(func() string { 70 | output, _ := exec.Command("ps", "aux").Output() 71 | return string(output) 72 | }, 10*time.Second).Should(ContainSubstring("sleep 1235")) 73 | }) 74 | 75 | It("starts a process with a log file specified", func() { 76 | var err error 77 | tempDir, err = ioutil.TempDir("", "cfdev-program-test-") 78 | Expect(err).NotTo(HaveOccurred()) 79 | 80 | logPath := filepath.Join(tempDir, "program-test.log") 81 | 82 | p, err = New(config.Config{ 83 | Label: "cfdev-program-test", 84 | Executable: "sh", 85 | Args: []string{"-c", "while true; do echo hello; sleep 1; done"}, 86 | Log: logPath, 87 | }) 88 | Expect(err).NotTo(HaveOccurred()) 89 | 90 | err = p.Start(nil) 91 | Expect(err).NotTo(HaveOccurred()) 92 | 93 | Eventually(func() string { 94 | output, _ := ioutil.ReadFile(logPath) 95 | return string(output) 96 | }, 10*time.Second).Should(ContainSubstring("hello")) 97 | }) 98 | }) 99 | -------------------------------------------------------------------------------- /resource/catalog_test.go: -------------------------------------------------------------------------------- 1 | package resource_test 2 | 3 | import ( 4 | . "github.com/onsi/ginkgo" 5 | . "github.com/onsi/gomega" 6 | 7 | "code.cloudfoundry.org/cfdev/resource" 8 | ) 9 | 10 | var _ = Describe("Catalog", func() { 11 | var catalog resource.Catalog 12 | BeforeEach(func() { 13 | catalog = resource.Catalog{ 14 | Items: []resource.Item{ 15 | { 16 | Name: "first-resource", 17 | URL: "first-resource-url", 18 | MD5: "1234", 19 | }, 20 | { 21 | Name: "second-resource", 22 | URL: "second-resource-url", 23 | MD5: "5678", 24 | }, 25 | { 26 | Name: "third-resource", 27 | URL: "third-resource-url", 28 | MD5: "abcd", 29 | }, 30 | }, 31 | } 32 | }) 33 | 34 | Describe("Lookup", func() { 35 | Context("the name exists", func() { 36 | It("returns the item", func() { 37 | item := catalog.Lookup("second-resource") 38 | Expect(item).ToNot(BeNil()) 39 | Expect(item.MD5).To(Equal("5678")) 40 | }) 41 | It("returns an item that can be edited", func() { 42 | item := catalog.Lookup("second-resource") 43 | item.MD5 = "beef" 44 | Expect(catalog.Lookup("second-resource").MD5).To(Equal("beef")) 45 | }) 46 | }) 47 | Context("when the name is missing", func() { 48 | It("returns nil", func() { 49 | item := catalog.Lookup("missing-resource") 50 | Expect(item).To(BeNil()) 51 | }) 52 | }) 53 | }) 54 | 55 | Describe("Remove", func() { 56 | Context("the name exists", func() { 57 | It("removes the item", func() { 58 | catalog.Remove("second-resource") 59 | Expect(catalog).To(Equal(resource.Catalog{ 60 | Items: []resource.Item{ 61 | { 62 | Name: "first-resource", 63 | URL: "first-resource-url", 64 | MD5: "1234", 65 | }, 66 | { 67 | Name: "third-resource", 68 | URL: "third-resource-url", 69 | MD5: "abcd", 70 | }, 71 | }, 72 | })) 73 | }) 74 | }) 75 | 76 | Context("when the name is missing", func() { 77 | It("does nothing", func() { 78 | catalog.Remove("missing-resource") 79 | Expect(catalog).To(Equal(resource.Catalog{ 80 | Items: []resource.Item{ 81 | { 82 | Name: "first-resource", 83 | URL: "first-resource-url", 84 | MD5: "1234", 85 | }, 86 | { 87 | Name: "second-resource", 88 | URL: "second-resource-url", 89 | MD5: "5678", 90 | }, 91 | { 92 | Name: "third-resource", 93 | URL: "third-resource-url", 94 | MD5: "abcd", 95 | }, 96 | }, 97 | })) 98 | }) 99 | }) 100 | }) 101 | }) 102 | -------------------------------------------------------------------------------- /pkg/cfdevd/client/client_test.go: -------------------------------------------------------------------------------- 1 | // +build darwin 2 | 3 | package client_test 4 | 5 | import ( 6 | "encoding/binary" 7 | "io/ioutil" 8 | "net" 9 | "os" 10 | "path/filepath" 11 | 12 | "code.cloudfoundry.org/cfdev/pkg/cfdevd/client" 13 | . "github.com/onsi/ginkgo" 14 | . "github.com/onsi/gomega" 15 | ) 16 | 17 | var _ = Describe("CFDevD Client", func() { 18 | var ( 19 | tmpDir string 20 | socketPath string 21 | subject *client.Client 22 | ) 23 | BeforeEach(func() { 24 | tmpDir, _ = ioutil.TempDir("", "cfdevd.") 25 | socketPath = filepath.Join(tmpDir, "cfdevd.socket") 26 | subject = client.New("TEST1", socketPath) 27 | }) 28 | AfterEach(func() { os.RemoveAll(tmpDir) }) 29 | 30 | Context("cfdevd socket exists", func() { 31 | var instructions chan byte 32 | var uninstallErrorCode int 33 | BeforeEach(func() { 34 | instructions = make(chan byte, 1) 35 | ln, err := net.Listen("unix", socketPath) 36 | Expect(err).NotTo(HaveOccurred()) 37 | Expect(socketPath).To(BeAnExistingFile()) 38 | go func() { 39 | conn, err := ln.Accept() 40 | Expect(err).NotTo(HaveOccurred()) 41 | handshake := make([]byte, 49, 49) 42 | binary.Read(conn, binary.LittleEndian, handshake) 43 | binary.Write(conn, binary.LittleEndian, handshake) 44 | instruction := make([]byte, 1, 1) 45 | binary.Read(conn, binary.LittleEndian, instruction) 46 | instructions <- instruction[0] 47 | if uninstallErrorCode == -1 { 48 | conn.Close() 49 | } else { 50 | binary.Write(conn, binary.LittleEndian, []byte{byte(uninstallErrorCode)}) 51 | } 52 | }() 53 | }) 54 | It("succeeds and sends the uninstall command to cfdevd", func() { 55 | uninstallErrorCode = 0 56 | serverName, err := subject.Uninstall() 57 | Expect(err).ToNot(HaveOccurred()) 58 | 59 | Eventually(instructions).Should(Receive(Equal(byte(1)))) 60 | Expect(serverName).To(Equal("TEST1")) 61 | }) 62 | Context("cfdevd stops after receiving uninstall command, thus closes connection before writing success code", func() { 63 | It("succeeds", func() { 64 | uninstallErrorCode = -1 65 | _, err := subject.Uninstall() 66 | Expect(err).ToNot(HaveOccurred()) 67 | 68 | Eventually(instructions).Should(Receive(Equal(byte(1)))) 69 | }) 70 | }) 71 | Context("cfdevd returns error to uninstall", func() { 72 | It("returns the error", func() { 73 | uninstallErrorCode = 1 74 | _, err := subject.Uninstall() 75 | Expect(err).To(MatchError("failed to uninstall cfdevd: errorcode: 1")) 76 | }) 77 | }) 78 | }) 79 | Context("cfdevd socket is specified but does not exist", func() { 80 | It("succeeds", func() { 81 | _, err := subject.Uninstall() 82 | Expect(err).ToNot(HaveOccurred()) 83 | }) 84 | }) 85 | }) 86 | -------------------------------------------------------------------------------- /pkg/analyticsd/daemon/daemon.go: -------------------------------------------------------------------------------- 1 | package daemon 2 | 3 | import ( 4 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/cloud_controller" 5 | "code.cloudfoundry.org/cfdev/pkg/analyticsd/command" 6 | "gopkg.in/segmentio/analytics-go.v3" 7 | "io" 8 | "log" 9 | "net/http" 10 | "time" 11 | ) 12 | 13 | //go:generate mockgen -package mocks -destination mocks/analytics.go gopkg.in/segmentio/analytics-go.v3 Client 14 | 15 | type Daemon struct { 16 | UUID string 17 | pluginVersion string 18 | osVersion string 19 | isBehindProxy string 20 | ccClient *cloud_controller.Client 21 | analyticsClient analytics.Client 22 | pollingInterval time.Duration 23 | logger *log.Logger 24 | lastTime time.Time 25 | doneChan chan bool 26 | } 27 | 28 | func New( 29 | ccHost string, 30 | UUID string, 31 | pluginVersion string, 32 | osVersion string, 33 | writer io.Writer, 34 | httpClient *http.Client, 35 | analyticsClient analytics.Client, 36 | pollingInterval time.Duration, 37 | ) *Daemon { 38 | logger := log.New(writer, "[ANALYTICSD] ", log.LstdFlags) 39 | ccClient := cloud_controller.New(ccHost, logger, httpClient) 40 | 41 | return &Daemon{ 42 | UUID: UUID, 43 | pluginVersion: pluginVersion, 44 | osVersion: osVersion, 45 | ccClient: ccClient, 46 | analyticsClient: analyticsClient, 47 | pollingInterval: pollingInterval, 48 | logger: logger, 49 | doneChan: make(chan bool, 1), 50 | } 51 | } 52 | 53 | func (d *Daemon) Start() { 54 | t := d.ccClient.FetchLatestTime() 55 | d.saveLatestTime(t) 56 | 57 | ticker := time.NewTicker(d.pollingInterval) 58 | 59 | for { 60 | select { 61 | case <-d.doneChan: 62 | return 63 | case <-ticker.C: 64 | err := d.do() 65 | if err != nil { 66 | d.logger.Println(err) 67 | } 68 | } 69 | } 70 | } 71 | 72 | func (d *Daemon) Stop() { 73 | err := d.do() 74 | if err != nil { 75 | d.logger.Println(err) 76 | } 77 | d.doneChan <- true 78 | } 79 | 80 | func (d *Daemon) do() error { 81 | events, err := d.ccClient.FetchEvents(d.lastTime) 82 | if err != nil { 83 | return err 84 | } 85 | 86 | for _, event := range events { 87 | d.saveLatestTime(event.Timestamp) 88 | 89 | cmd, exists := command.New(event.Type, d.ccClient, d.analyticsClient, event.Timestamp, d.UUID, d.pluginVersion, d.osVersion, d.logger) 90 | if !exists { 91 | continue 92 | } 93 | 94 | err = cmd.HandleResponse(event.Metadata) 95 | if err != nil { 96 | return err 97 | } 98 | } 99 | 100 | return nil 101 | } 102 | 103 | func (d *Daemon) saveLatestTime(t time.Time) { 104 | if t.After(d.lastTime) { 105 | d.lastTime = t 106 | } 107 | } 108 | --------------------------------------------------------------------------------