├── solo ├── base │ ├── version.txt │ ├── Makefile │ ├── unbound-skydns.conf │ └── README.md ├── helios-restart ├── helios-solo ├── docker │ └── Dockerfile ├── helios-down ├── helios-cleanup ├── helios-solo.service └── helios-env ├── .github ├── CODEOWNERS └── stale.yml ├── .test-excludes ├── NOTICE ├── docs ├── examples │ ├── README.md │ └── nginx.md ├── automatic_master_lookup.md ├── event_senders.md ├── README.md └── developer_guide.md ├── helios-tools └── src │ ├── test │ ├── resources │ │ ├── job_config_with_runtime.json │ │ ├── job_config_extra_labels.json │ │ ├── job_config_extra_metadata.json │ │ ├── job_config.json │ │ ├── job_config_extra_capabilities.json │ │ └── logback-test.xml │ └── java │ │ └── com │ │ └── spotify │ │ └── helios │ │ └── cli │ │ └── TestUtils.java │ └── main │ ├── resources │ └── logback.xml │ └── java │ └── com │ └── spotify │ └── helios │ └── cli │ └── command │ ├── CliCommand.java │ └── TargetAndClient.java ├── helios-testing └── src │ ├── test │ ├── resources │ │ ├── image_info.json │ │ ├── helios.conf │ │ ├── helios_job_config.json │ │ └── helios-base.conf │ └── java │ │ └── com │ │ └── spotify │ │ └── helios │ │ └── testing │ │ ├── TemporaryJobsBuilderTest.java │ │ ├── CapturingAppender.java │ │ └── JobsTest.java │ └── main │ └── java │ └── com │ └── spotify │ └── helios │ └── testing │ ├── HostPickingStrategy.java │ ├── Prober.java │ ├── HeliosDeploymentException.java │ ├── Deployer.java │ ├── LogStreamFollower.java │ └── HeliosDeployment.java ├── helios-client └── src │ ├── test │ ├── resources │ │ ├── portmapping-internal-port-only.json │ │ ├── portmapping-defaults.json │ │ ├── portmapping-invalid-ip.json │ │ ├── portmapping-serialized-internal-port-only.json │ │ ├── portmapping-partial.json │ │ ├── portmapping-full.json │ │ ├── portmapping-unknown-fields.json │ │ ├── job-with-no-ports.json │ │ ├── job-with-no-external-ports.json │ │ ├── job-with-grace-period.json │ │ ├── job-with-external-ports.json │ │ ├── com │ │ │ └── spotify │ │ │ │ └── helios │ │ │ │ └── common │ │ │ │ └── job-with-bad-registration.json │ │ ├── job-with-external-ports-and-grace-period.json │ │ ├── UIDCACert.pem │ │ └── UIDCACert.key │ └── java │ │ └── com │ │ └── spotify │ │ └── helios │ │ └── common │ │ ├── PeriodicResolverTest.java │ │ └── VersionCompatibilityTest.java │ └── main │ └── java │ └── com │ └── spotify │ └── helios │ ├── common │ ├── Clock.java │ ├── descriptors │ │ ├── Goal.java │ │ ├── JobIdParseException.java │ │ ├── ThrottleState.java │ │ └── Descriptor.java │ ├── SystemClock.java │ ├── Version.java.template │ ├── HeliosException.java │ ├── Hash.java │ ├── protocol │ │ ├── JobDeleteResponse.java │ │ ├── HostRegisterResponse.java │ │ ├── HostDeregisterResponse.java │ │ ├── VersionResponse.java │ │ └── TaskStatusEvents.java │ ├── HeliosRuntimeException.java │ ├── LoggingConfig.java │ └── VersionCheckResponse.java │ └── client │ ├── RequestDispatcher.java │ ├── HttpConnector.java │ └── Endpoint.java ├── src └── deb │ ├── helios-agent │ ├── default │ ├── prerm │ ├── helios-agent.service │ ├── control │ ├── helios-agent-wrapper │ ├── upstart │ └── postinst │ ├── helios-master │ ├── default │ ├── prerm │ ├── helios-master.service │ ├── control │ ├── helios-master-wrapper │ ├── upstart │ └── postinst │ ├── helios │ └── control │ ├── helios-services │ └── control │ └── helios-solo │ └── control ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── helios-integration-tests └── src │ └── test │ └── resources │ ├── helios.conf │ ├── helios-base.conf │ └── logback-test.xml ├── AUTHORS ├── codecov.yml ├── helios-system-tests ├── src │ └── main │ │ ├── resources │ │ ├── syslog-test-image │ │ │ └── Dockerfile │ │ └── agent-upgrades-task-file-test │ │ │ └── task-config.json │ │ └── java │ │ └── com │ │ └── spotify │ │ └── helios │ │ └── system │ │ ├── MasterResolutionFailureMessageTest.java │ │ └── ZooKeeperBadNodeTest.java └── deployment-group-history.json ├── .gitignore ├── helios-services └── src │ ├── main │ ├── resources │ │ ├── agent-banner.txt │ │ └── master-banner.txt │ └── java │ │ └── com │ │ └── spotify │ │ └── helios │ │ ├── servicescommon │ │ ├── ServiceMainFactory.java │ │ ├── coordination │ │ │ ├── NodeUpdaterFactory.java │ │ │ ├── NodeUpdater.java │ │ │ ├── ZooKeeperOperation.java │ │ │ ├── ZooKeeperNodeUpdaterFactory.java │ │ │ ├── ZooKeeperClientProvider.java │ │ │ ├── Node.java │ │ │ ├── ZooKeeperHealthChecker.java │ │ │ ├── CuratorClientFactory.java │ │ │ ├── PathFactory.java │ │ │ └── Check.java │ │ ├── EventSender.java │ │ ├── statistics │ │ │ ├── MetricsContext.java │ │ │ ├── Metrics.java │ │ │ ├── NoopMetricsContext.java │ │ │ ├── MasterMetrics.java │ │ │ ├── NoopZooKeeperMetrics.java │ │ │ ├── NoopMasterMetrics.java │ │ │ ├── NoopMetrics.java │ │ │ ├── SupervisorMetrics.java │ │ │ ├── ZooKeeperMetrics.java │ │ │ ├── DockerVersionSupplier.java │ │ │ ├── MeterRates.java │ │ │ └── MetricsContextImpl.java │ │ ├── ReactorFactory.java │ │ ├── Reactor.java │ │ ├── VersionedValue.java │ │ ├── KafkaRecord.java │ │ ├── CommonConfiguration.java │ │ ├── FastForwardConfig.java │ │ └── InterruptingExecutionThreadService.java │ │ ├── agent │ │ ├── Sleeper.java │ │ ├── RetryIntervalPolicy.java │ │ ├── HealthChecker.java │ │ ├── ThreadSleeper.java │ │ ├── RetryScheduler.java │ │ ├── StatusUpdater.java │ │ ├── DockerDaemonHealthChecker.java │ │ ├── AgentModelTaskResource.java │ │ ├── AgentModelTaskStatusResource.java │ │ ├── NoOpContainerDecorator.java │ │ └── ContainerDecorator.java │ │ ├── master │ │ ├── resources │ │ │ ├── RequestUser.java │ │ │ └── MastersResource.java │ │ ├── JobAlreadyDeployedException.java │ │ ├── JobExistsException.java │ │ ├── HostNotFoundException.java │ │ ├── http │ │ │ └── PATCH.java │ │ ├── DeploymentGroupExistsException.java │ │ ├── DeploymentGroupDoesNotExistException.java │ │ ├── JobNotDeployedException.java │ │ ├── JobStillDeployedException.java │ │ ├── JobDoesNotExistException.java │ │ ├── HostStillInUseException.java │ │ ├── TokenVerificationException.java │ │ └── metrics │ │ │ ├── ReportingResourceMethodDispatchAdapter.java │ │ │ ├── HealthCheckGauge.java │ │ │ └── ReportingResourceMethodDispatchProvider.java │ │ └── rollingupdate │ │ ├── RolloutPlanner.java │ │ ├── RollingUpdateError.java │ │ └── RollingUpdateOp.java │ ├── assembly │ └── helios-solo.xml │ └── test │ └── java │ └── com │ └── spotify │ └── helios │ └── agent │ └── AgentParserTest.java ├── create_artifacts.sh ├── helios-service-registration ├── src │ └── main │ │ └── java │ │ └── com │ │ └── spotify │ │ └── helios │ │ └── serviceregistration │ │ ├── NopServiceRegistrationHandle.java │ │ ├── ServiceRegistrationHandle.java │ │ ├── ServiceRegistrarLoadingException.java │ │ ├── NopServiceRegistrarFactory.java │ │ ├── NopServiceRegistrar.java │ │ └── ServiceRegistrar.java └── pom.xml ├── helios-testing-common └── src │ └── main │ ├── resources │ ├── META-INF │ │ └── services │ │ │ └── com.spotify.helios.serviceregistration.ServiceRegistrarFactory │ └── logback-access.xml │ └── java │ └── com │ └── spotify │ └── helios │ ├── MockServiceRegistrarRegistry.java │ └── MockServiceRegistrarFactory.java ├── bin ├── helios-initialize-acl ├── helios ├── helios-agent └── helios-master ├── findbugs-exclude.xml ├── pubkey.asc ├── CONTRIBUTING.md └── .circleci └── Dockerfile /solo/base/version.txt: -------------------------------------------------------------------------------- 1 | 0.8 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @spotify/helios 2 | -------------------------------------------------------------------------------- /.test-excludes: -------------------------------------------------------------------------------- 1 | # circle.sh writes excludes here 2 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Helios 2 | Copyright (c) 2014 Spotify AB 3 | -------------------------------------------------------------------------------- /solo/helios-restart: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | PATH=.:$PATH 3 | helios-down 4 | echo 5 | helios-up 6 | -------------------------------------------------------------------------------- /docs/examples/README.md: -------------------------------------------------------------------------------- 1 | Specific use-cases with Helios. At the moment just [Nginx](nginx.md). 2 | -------------------------------------------------------------------------------- /helios-tools/src/test/resources/job_config_with_runtime.json: -------------------------------------------------------------------------------- 1 | { 2 | "runtime": "nvidia" 3 | } 4 | -------------------------------------------------------------------------------- /helios-testing/src/test/resources/image_info.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "spotify/busybox:latest" 3 | } 4 | -------------------------------------------------------------------------------- /solo/helios-solo: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | eval $(PATH=.:$PATH helios-env) 3 | helios -z $HELIOS_URI "$@" 4 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/portmapping-internal-port-only.json: -------------------------------------------------------------------------------- 1 | { 2 | "internalPort" : 456 3 | } 4 | -------------------------------------------------------------------------------- /src/deb/helios-agent/default: -------------------------------------------------------------------------------- 1 | ENABLED=yes 2 | 3 | HELIOS_AGENT_JVM_OPTS= 4 | 5 | HELIOS_AGENT_OPTS= 6 | -------------------------------------------------------------------------------- /src/deb/helios-master/default: -------------------------------------------------------------------------------- 1 | ENABLED=yes 2 | 3 | HELIOS_MASTER_JVM_OPTS= 4 | 5 | HELIOS_MASTER_OPTS= 6 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spotify/helios/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /helios-integration-tests/src/test/resources/helios.conf: -------------------------------------------------------------------------------- 1 | ../../../../helios-testing/src/test/resources/helios.conf -------------------------------------------------------------------------------- /helios-client/src/test/resources/portmapping-defaults.json: -------------------------------------------------------------------------------- 1 | {"externalPort":123,"internalPort":456,"protocol":"tcp"} 2 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/portmapping-invalid-ip.json: -------------------------------------------------------------------------------- 1 | { 2 | "ip" : "foobar", 3 | "internalPort" : 456 4 | } 5 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/portmapping-serialized-internal-port-only.json: -------------------------------------------------------------------------------- 1 | {"internalPort":456,"protocol":"tcp"} 2 | -------------------------------------------------------------------------------- /helios-integration-tests/src/test/resources/helios-base.conf: -------------------------------------------------------------------------------- 1 | ../../../../helios-testing/src/test/resources/helios-base.conf -------------------------------------------------------------------------------- /helios-client/src/test/resources/portmapping-partial.json: -------------------------------------------------------------------------------- 1 | { 2 | "externalPort" : 123, 3 | "internalPort" : 456 4 | } 5 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/portmapping-full.json: -------------------------------------------------------------------------------- 1 | {"externalPort":123,"internalPort":456,"ip":"1.2.3.4","protocol":"udp"} 2 | -------------------------------------------------------------------------------- /helios-tools/src/test/resources/job_config_extra_labels.json: -------------------------------------------------------------------------------- 1 | { 2 | "labels": { 3 | "foo": "bar", 4 | "baz": "qux" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip -------------------------------------------------------------------------------- /helios-tools/src/test/resources/job_config_extra_metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "foo" : "bar", 4 | "baz" : "qux" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /solo/docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM spotify/helios-solo-base:0.8 2 | 3 | EXPOSE 5801 4 | 5 | ADD start.sh / 6 | ADD *.jar / 7 | ENTRYPOINT ["/start.sh"] 8 | -------------------------------------------------------------------------------- /helios-tools/src/test/resources/job_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "JVM_ARGS": "-Ddw.feature.randomFeatureFlagEnabled=true" 4 | }, 5 | "gracePeriod": 100 6 | } 7 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/portmapping-unknown-fields.json: -------------------------------------------------------------------------------- 1 | { 2 | "foo" : "bar", 3 | "externalPort" : 123, 4 | "internalPort" : 456, 5 | "something" : "random" 6 | } 7 | -------------------------------------------------------------------------------- /helios-testing/src/test/resources/helios.conf: -------------------------------------------------------------------------------- 1 | helios.testing.profile = local 2 | helios.testing.profile = ${?HELIOS_TESTING_PROFILE} 3 | 4 | helios.solo.profile = local 5 | helios.solo.profile = ${?HELIOS_SOLO_PROFILE} 6 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/job-with-no-ports.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "foobar:1:253df2150e8993ba14086c106961377ebeae0185", 3 | "image": "example.net/foo/bar", 4 | "volumes": { 5 | "/some/path:ro": "/another/path" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /helios-tools/src/test/resources/job_config_extra_capabilities.json: -------------------------------------------------------------------------------- 1 | { 2 | "addCapabilities": [ 3 | "cap_one", 4 | "cap_two" 5 | ], 6 | "dropCapabilities": [ 7 | "cap_three", 8 | "cap_four" 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /solo/helios-down: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if ! docker inspect helios-solo-container &> /dev/null; then 3 | echo 'helios-solo not running' 4 | exit 1 5 | fi 6 | 7 | docker kill helios-solo-container > /dev/null 8 | docker rm helios-solo-container > /dev/null 9 | echo 'helios-solo stopped' 10 | -------------------------------------------------------------------------------- /src/deb/helios/control: -------------------------------------------------------------------------------- 1 | Package: helios 2 | Version: [[version]] 3 | Section: non-free/net 4 | Priority: optional 5 | Architecture: all 6 | Depends: java7-runtime-headless 7 | Maintainer: Daniel Norberg 8 | Description: Helios Command Line Tools 9 | Distribution: development 10 | -------------------------------------------------------------------------------- /src/deb/helios-agent/prerm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Stop helios-agent 3 | if which initctl >/dev/null && initctl version | grep -q upstart; then 4 | # Using upstart 5 | initctl stop helios-agent || true 6 | else 7 | # Using SysV init scripts 8 | /etc/init.d/helios-agent stop || true 9 | fi 10 | 11 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Daniel Norberg 2 | Drew Csillag 3 | Mats Linander 4 | Philip Cristiano 5 | Rohan Singh 6 | Ryan Culbertson 7 | Simon Cohen 8 | Matt Brown 9 | -------------------------------------------------------------------------------- /src/deb/helios-agent/helios-agent.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Helios agent daemon 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | Restart=always 8 | ExecStart=/usr/bin/helios-agent-wrapper 9 | ExecStopPost=/bin/sleep 5 10 | User=helios 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /src/deb/helios-master/prerm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Stop helios-master 3 | if which initctl >/dev/null && initctl version | grep -q upstart; then 4 | # Using upstart 5 | initctl stop helios-master || true 6 | else 7 | # Using SysV init scripts 8 | /etc/init.d/helios-master stop || true 9 | fi 10 | 11 | -------------------------------------------------------------------------------- /src/deb/helios-master/helios-master.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Helios master daemon 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | Restart=always 8 | ExecStart=/usr/bin/helios-master-wrapper 9 | ExecStopPost=/bin/sleep 5 10 | User=helios 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /src/deb/helios-services/control: -------------------------------------------------------------------------------- 1 | Package: helios-services 2 | Version: [[version]] 3 | Section: non-free/net 4 | Priority: optional 5 | Architecture: all 6 | Depends: java8-runtime-headless 7 | Maintainer: Daniel Norberg 8 | Description: Helios services common files 9 | Distribution: development 10 | -------------------------------------------------------------------------------- /src/deb/helios-agent/control: -------------------------------------------------------------------------------- 1 | Package: helios-agent 2 | Version: [[version]] 3 | Section: non-free/net 4 | Priority: optional 5 | Architecture: all 6 | Depends: java8-runtime-headless, helios-services (= [[version]]) 7 | Maintainer: Daniel Norberg 8 | Description: Helios Agent 9 | Distribution: development 10 | -------------------------------------------------------------------------------- /src/deb/helios-master/control: -------------------------------------------------------------------------------- 1 | Package: helios-master 2 | Version: [[version]] 3 | Section: non-free/net 4 | Priority: optional 5 | Architecture: all 6 | Depends: java8-runtime-headless, helios-services (= [[version]]) 7 | Maintainer: Daniel Norberg 8 | Description: Helios Master 9 | Distribution: development 10 | -------------------------------------------------------------------------------- /helios-testing/src/test/resources/helios_job_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "ports": { 3 | "http": { 4 | "externalPort": 80, 5 | "internalPort": 80, 6 | "protocol": "tcp" 7 | }, 8 | "https": { 9 | "externalPort": 123, 10 | "internalPort": 456, 11 | "protocol": "tcp" 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /solo/base/Makefile: -------------------------------------------------------------------------------- 1 | DOCKER_REPOSITORY ?= spotify/helios-solo-base 2 | DOCKER_TAG = $(shell cat version.txt) 3 | 4 | DOCKER ?= docker 5 | export DOCKER 6 | 7 | .PHONY: all image push 8 | 9 | image: 10 | $(DOCKER) build -t $(DOCKER_REPOSITORY):$(DOCKER_TAG) . 11 | 12 | push: image 13 | $(DOCKER) push $(DOCKER_REPOSITORY):$(DOCKER_TAG) 14 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | daysUntilStale: 60 2 | daysUntilClose: 7 3 | exemptLabels: 4 | - pinned 5 | - security 6 | staleLabel: stale 7 | markComment: > 8 | This issue has been automatically marked as stale because it has not had 9 | recent activity. It will be closed if no further activity occurs. Thank you 10 | for your contributions. 11 | closeComment: false 12 | only: issues -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: 2 | layout: header, diff 3 | 4 | coverage: 5 | status: 6 | # set a github PR status for overall project coverage with an automatically 7 | # calculated coverage target 8 | project: 9 | default: 10 | target: auto 11 | 12 | # patch coverage doesn't seem very helpful 13 | patch: 14 | default: 15 | enabled: false 16 | -------------------------------------------------------------------------------- /helios-system-tests/src/main/resources/syslog-test-image/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM spotify/alpine:latest 2 | 3 | RUN curl -L -o /tmp/syslog-redirector.zip https://github.com/spotify/syslog-redirector/releases/download/0.0.5/syslog-redirector.zip 4 | RUN unzip /tmp/syslog-redirector.zip syslog-redirector -d / && rm /tmp/syslog-redirector.zip 5 | 6 | ENTRYPOINT ["/bin/sh"] 7 | CMD ["-c", "echo should-be-redirected"] 8 | -------------------------------------------------------------------------------- /src/deb/helios-agent/helios-agent-wrapper: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This wrapper script allows initialization of 4 | # environment variables since systemd's Environment and 5 | # EnvironmentFile directives don't support running 6 | # arbitrary commands. 7 | 8 | DEFAULTFILE=/etc/default/helios-agent 9 | 10 | [ -f $DEFAULTFILE ] && . $DEFAULTFILE 11 | 12 | exec /usr/bin/helios-agent ${HELIOS_AGENT_OPTS} 13 | -------------------------------------------------------------------------------- /src/deb/helios-master/helios-master-wrapper: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This wrapper script allows initialization of 4 | # environment variables since systemd's Environment and 5 | # EnvironmentFile directives don't support running 6 | # arbitrary commands. 7 | 8 | DEFAULTFILE=/etc/default/helios-master 9 | 10 | [ -f $DEFAULTFILE ] && . $DEFAULTFILE 11 | 12 | exec /usr/bin/helios-master ${HELIOS_MASTER_OPTS} 13 | -------------------------------------------------------------------------------- /docs/automatic_master_lookup.md: -------------------------------------------------------------------------------- 1 | If you have multiple Helios masters, you can setup DNS records so the CLI can discover masters 2 | automatically for your domain: 3 | 4 | helios -d example.net 5 | 6 | What we're actually doing for the `-d` flag is looking up the `_helios._https.` SRV record, 7 | falling back to `_helios._http.` if no HTTPS SRV records are found, 8 | and selecting a master from the returned endpoints. 9 | -------------------------------------------------------------------------------- /helios-tools/src/main/resources/logback.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | %date{HH:mm:ss.SSS} %-5level %logger{0}: %msg%n 6 | 7 | System.err 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /solo/base/unbound-skydns.conf: -------------------------------------------------------------------------------- 1 | server: 2 | interface: 0.0.0.0 3 | port: 53 4 | tcp-upstream: no 5 | num-threads: 1 6 | incoming-num-tcp: 256 7 | outgoing-num-tcp: 256 8 | access-control: 0.0.0.0/0 allow 9 | do-not-query-localhost: no 10 | max-udp-size: 32768 11 | edns-buffer-size: 32768 12 | 13 | remote-control: 14 | control-interface: 0.0.0.0 15 | 16 | forward-zone: 17 | name: "." 18 | forward-addr: "127.0.0.1@5353" 19 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/job-with-no-external-ports.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "foobar:1:65597d013748b8eac1d86ac5088ab6e6bf9546b4", 3 | "image": "example.net/foo/bar", 4 | "ports": { 5 | "http": { 6 | "internalPort": 8080, 7 | "protocol": "tcp" 8 | } 9 | }, 10 | "registration": { 11 | "my-cool-service/http": { 12 | "ports": { 13 | "http": {} 14 | } 15 | } 16 | }, 17 | "volumes": { 18 | "/some/path:ro": "/another/path" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/deb/helios-solo/control: -------------------------------------------------------------------------------- 1 | Package: helios-solo 2 | Version: [[version]] 3 | Section: non-free/net 4 | Priority: optional 5 | Architecture: all 6 | Depends: docker-ce | docker.io | lxc-docker | docker-engine, helios, jq, bind9-host 7 | Provides: helios-standalone 8 | Conflicts: helios-standalone 9 | Replaces: helios-standalone 10 | Maintainer: Rohan Singh 11 | Description: helios-solo provides a local Helios cluster running in a Docker container 12 | Distribution: development 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build products and artifacts 2 | *.html 3 | .m2-repository/ 4 | target/ 5 | pom.xml.versionsBackup 6 | docker/tmp/ 7 | helios-integration-tests/helios-reports/ 8 | helios-testing/helios-reports/ 9 | 10 | # Stuff from various IDE's and editors 11 | *.iml 12 | *~ 13 | .idea/* 14 | 15 | # Mac OS X Finder 16 | .DS_Store 17 | 18 | # Vagrant 19 | .vagrant 20 | 21 | # Generated by maven 22 | helios-client/src/main/java/com/spotify/helios/common/Version.java 23 | helios-client/dependency-reduced-pom.xml 24 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/job-with-grace-period.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "foobar:1:854145e9a5e09a8c635c0f584f45d5f26342bef7", 3 | "image": "example.net/foo/bar", 4 | "gracePeriod": 10, 5 | "ports": { 6 | "http": { 7 | "internalPort": 8080, 8 | "protocol": "tcp" 9 | } 10 | }, 11 | "registration": { 12 | "my-cool-service/http": { 13 | "ports": { 14 | "http": {} 15 | } 16 | } 17 | }, 18 | "volumes": { 19 | "/some/path:ro": "/another/path" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/job-with-external-ports.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "foobar:1:104e77cf3aa8d497526e34e8631348069a544e0c", 3 | "image": "example.net/foo/bar", 4 | "ports": { 5 | "http": { 6 | "internalPort": 8080, 7 | "externalPort": 8080, 8 | "protocol": "tcp" 9 | } 10 | }, 11 | "registration": { 12 | "my-cool-service/http": { 13 | "ports": { 14 | "http": {} 15 | } 16 | } 17 | }, 18 | "volumes": { 19 | "/some/path:ro": "/another/path" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /helios-services/src/main/resources/agent-banner.txt: -------------------------------------------------------------------------------- 1 | ___ ___ .__ .__ _____ __ 2 | / | \ ____ | | |__| ____ ______ / _ \ ____ ____ _____/ |_ 3 | / ~ \_/ __ \| | | |/ _ \/ ___/ / /_\ \ / ___\_/ __ \ / \ __\ 4 | \ Y /\ ___/| |_| ( <_> )___ \ / | \/ /_/ > ___/| | \ | 5 | \___|_ / \___ >____/__|\____/____ > \____|__ /\___ / \___ >___| /__| 6 | \/ \/ \/ \//_____/ \/ \/ 7 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/com/spotify/helios/common/job-with-bad-registration.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "job-with-bad-registration:1:4ee3a68429951bb9603b753c73fcefab27420dbe", 3 | "image": "example.net/foo/bar", 4 | "ports": { 5 | "http": { 6 | "internalPort": 8080, 7 | "protocol": "tcp" 8 | } 9 | }, 10 | "registration": { 11 | "my-cool-service/http": { 12 | "ports": { 13 | "http": {} 14 | } 15 | }, 16 | "volumes": { 17 | "/some/path:ro": "/another/path" 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/job-with-external-ports-and-grace-period.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "foobar:1:48d9888333089d782fc2bb0e1681c0afe1dc1454", 3 | "image": "example.net/foo/bar", 4 | "gracePeriod": 500, 5 | "ports": { 6 | "http": { 7 | "internalPort": 8080, 8 | "externalPort": 8080, 9 | "protocol": "tcp" 10 | } 11 | }, 12 | "registration": { 13 | "my-cool-service/http": { 14 | "ports": { 15 | "http": {} 16 | } 17 | } 18 | }, 19 | "volumes": { 20 | "/some/path:ro": "/another/path" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /solo/base/README.md: -------------------------------------------------------------------------------- 1 | helios-solo-base 2 | === 3 | 4 | This image contains dependencies for spotify/helios-solo. The only reason it exists is to speed up 5 | building the spotify/helios-solo image. 6 | 7 | Build & release 8 | --- 9 | This image is built and released manually. If you make changes, bump `version.txt` and then run 10 | `make push` to make and push the image. The reason we do this is to avoid unnecessarily rebuilding 11 | this image with every Helios build when it rarely changes. 12 | 13 | Doing this also speeds up `helios-use latest` for clients, since most of the layers for helios-solo 14 | never change. 15 | -------------------------------------------------------------------------------- /helios-integration-tests/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /docs/examples/nginx.md: -------------------------------------------------------------------------------- 1 | Create an nginx job using the nginx container image, exposing it on the host on port 8080 2 | 3 | helios create nginx:v1 nginx:1.7.1 -p http=80:8080 4 | 5 | Check that the job is listed 6 | 7 | helios jobs 8 | 9 | List helios hosts 10 | 11 | helios hosts 12 | 13 | Deploy the nginx job on any of the hosts 14 | 15 | helios deploy nginx:v1 ... 16 | 17 | Check the job status 18 | 19 | helios status 20 | 21 | Curl the nginx container when it's started running 22 | 23 | curl :8080 24 | 25 | Undeploy the nginx job 26 | 27 | helios undeploy -a nginx:v1 28 | 29 | Remove the nginx job 30 | 31 | helios remove nginx:v1 32 | 33 | -------------------------------------------------------------------------------- /solo/helios-cleanup: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo 'Removing all helios-solo jobs and containers...' 3 | 4 | # Instruct helios to undeploy and remove all jobs 5 | RUNNING=$(docker inspect -f '{{ .State.Running }}' helios-solo-container 2>/dev/null) 6 | if [ "$RUNNING" == "true" ]; then 7 | JOBS=$(PATH=.:$PATH helios-solo jobs -q) 8 | for job in $JOBS; do 9 | PATH=.:$PATH helios-solo undeploy -a --yes $job 10 | PATH=.:$PATH helios-solo remove --yes $job 11 | done 12 | fi 13 | 14 | # Kill containers until they're gone 15 | while true; do 16 | CTRS=$(docker ps -a | grep helios-solo-host- | awk '{ print $(NF) }') 17 | if [ -z "$CTRS" ]; then break; fi 18 | for ctr in $CTRS; do 19 | docker kill $ctr 20 | docker rm $ctr 21 | done 22 | sleep 1 23 | done 24 | -------------------------------------------------------------------------------- /helios-system-tests/deployment-group-history.json: -------------------------------------------------------------------------------- 1 | { 2 | "my_group": [ 3 | { 4 | "action": null, 5 | "deploymentGroup": { 6 | "hostSelectors": [ 7 | { 8 | "label": "foo", 9 | "operand": "bar", 10 | "operator": "EQUALS" 11 | } 12 | ], 13 | "name": "my_group", 14 | "rolloutOptions": { 15 | "migrate": true, 16 | "parallelism": 1, 17 | "timeout": 300 18 | }, 19 | "jobId": "job_test_c91ff698:v9980bb70:084ce7789f046296c639b8a85cb782e639b53870" 20 | }, 21 | "deploymentGroupState": "ROLLING_OUT", 22 | "rolloutTaskStatus": null, 23 | "target": null, 24 | "timestamp": 1437420186023, 25 | "jobId": null 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /src/deb/helios-master/upstart: -------------------------------------------------------------------------------- 1 | # helios-master - manages jobs across helios agents 2 | 3 | description "helios master" 4 | author "Rohan Singh " 5 | 6 | start on runlevel [2345] 7 | stop on runlevel [!2345] 8 | 9 | kill signal SIGKILL 10 | 11 | respawn 12 | respawn limit unlimited 13 | 14 | env DEFAULTFILE=/etc/default/helios-master 15 | 16 | setuid helios 17 | 18 | pre-start script 19 | [ -f $DEFAULTFILE ] && . $DEFAULTFILE 20 | 21 | # don't start unless explicitly enabled in config 22 | if [ -z "$ENABLED" ] ; then 23 | stop; exit 0; 24 | fi 25 | end script 26 | 27 | script 28 | [ -f $DEFAULTFILE ] && . $DEFAULTFILE 29 | export HELIOS_MASTER_JVM_OPTS 30 | exec /usr/bin/helios-master $HELIOS_MASTER_OPTS 31 | end script 32 | 33 | # prevent respawning more than once every 5 seconds 34 | post-stop exec sleep 5 35 | -------------------------------------------------------------------------------- /src/deb/helios-agent/upstart: -------------------------------------------------------------------------------- 1 | # helios-agent - manages jobs across helios agents 2 | 3 | description "helios agent" 4 | author "Rohan Singh " 5 | 6 | start on runlevel [2345] 7 | stop on runlevel [!2345] 8 | 9 | kill signal SIGKILL 10 | 11 | respawn 12 | respawn limit unlimited 13 | 14 | env DEFAULTFILE=/etc/default/helios-agent 15 | 16 | setuid helios 17 | chdir /var/lib/helios-agent 18 | 19 | pre-start script 20 | [ -f $DEFAULTFILE ] && . $DEFAULTFILE 21 | 22 | # don't start unless explicitly enabled in config 23 | if [ -z "$ENABLED" ] ; then 24 | stop; exit 0; 25 | fi 26 | end script 27 | 28 | script 29 | [ -f $DEFAULTFILE ] && . $DEFAULTFILE 30 | export HELIOS_AGENT_JVM_OPTS 31 | exec /usr/bin/helios-agent $HELIOS_AGENT_OPTS 32 | end script 33 | 34 | # prevent respawning more than once every 5 seconds 35 | post-stop exec sleep 5 36 | -------------------------------------------------------------------------------- /helios-services/src/assembly/helios-solo.xml: -------------------------------------------------------------------------------- 1 | 4 | helios-solo 5 | 6 | zip 7 | 8 | 9 | 10 | ../solo 11 | / 12 | 13 | helios-* 14 | 15 | 16 | 17 | 18 | 19 | ../docs/helios_solo.md 20 | / 21 | README.md 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/ServiceMainFactory.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon; 22 | 23 | public interface ServiceMainFactory { 24 | 25 | ServiceMain newService(final String[] args) throws Exception; 26 | } 27 | -------------------------------------------------------------------------------- /helios-testing/src/main/java/com/spotify/helios/testing/HostPickingStrategy.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.testing; 22 | 23 | import java.util.List; 24 | 25 | public interface HostPickingStrategy { 26 | String pickHost(final List hosts); 27 | } 28 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/coordination/NodeUpdaterFactory.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.coordination; 22 | 23 | 24 | public interface NodeUpdaterFactory { 25 | 26 | ZooKeeperNodeUpdater create(String path); 27 | } 28 | -------------------------------------------------------------------------------- /solo/helios-solo.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Spotify Helios Solo 3 | Documentation=https://github.com/spotify/helios/tree/master/docs 4 | After=docker.socket 5 | Requires=docker.socket 6 | 7 | [Service] 8 | Restart=on-failure 9 | RestartSec=10 10 | TimeoutStartSec=0 11 | ExecStartPre=-/usr/bin/docker kill helios-solo-container 12 | ExecStartPre=-/usr/bin/docker rm helios-solo-container 13 | ExecStartPre=-/usr/bin/docker pull spotify/helios-solo 14 | ExecStart=/bin/sh -c "/usr/bin/docker run \ 15 | --name=helios-solo-container \ 16 | -v /var/run/docker.sock:/var/run/docker.sock \ 17 | -e DOCKER_HOST=unix:///var/run/docker.sock \ 18 | -e HELIOS_NAME=solo.local. \ 19 | -e HOST_ADDRESS=$(ip -4 addr show docker0 | grep -Po 'inet \\K[\\d.]+') \ 20 | -e REGISTRAR_HOST_FORMAT='_spotify-$${service}._$${protocol}.services.$${domain}' \ 21 | -p 5801:5801 \ 22 | spotify/helios-solo" 23 | ExecStop=/usr/bin/docker kill helios-solo-container 24 | 25 | [Install] 26 | WantedBy=multi-user.target 27 | -------------------------------------------------------------------------------- /create_artifacts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -ex 2 | 3 | # Tar up the staged release, all the pom files, and some build files. We will use these in 4 | # subsequent build steps to perform the actual release. 5 | tar -zcvf target/helios-staged-release.tar.gz `find . -name nexus-staging && find . -name pom.xml` 6 | 7 | # Copy all debian packages into target/debs, and tar them into target/helios-debs.tar.gz 8 | mkdir target/debs 9 | find . -name *.deb -type f -not -path "./target/*" -exec cp {} target/debs/ \; 10 | tar -C target/debs -zcf target/helios-debs.tar.gz . 11 | 12 | # Copy helios-solo script archive into target/helios-solo.zip 13 | cp helios-services/target/helios-solo.zip ./target 14 | 15 | # Output build version into file for later Jenkins items 16 | VERSION=$(egrep -o '.*' -m 1 pom.xml | sed 's/\(.*\)<\/version>/\1/') 17 | echo ${VERSION} > target/version 18 | 19 | # Output current git commit hash into file for later Jenkins items 20 | git rev-parse HEAD > target/commit_hash 21 | -------------------------------------------------------------------------------- /helios-testing/src/main/java/com/spotify/helios/testing/Prober.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.testing; 22 | 23 | import com.spotify.helios.common.descriptors.PortMapping; 24 | 25 | public interface Prober { 26 | boolean probe(String host, PortMapping portMapping); 27 | } 28 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/EventSender.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon; 22 | 23 | import io.dropwizard.lifecycle.Managed; 24 | 25 | public interface EventSender extends Managed { 26 | 27 | void send(String topic, byte[] message); 28 | } 29 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/Clock.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common; 22 | 23 | import org.joda.time.Instant; 24 | 25 | /** 26 | * Mostly for testing, but an interface that represents the system clock. 27 | */ 28 | public interface Clock { 29 | Instant now(); 30 | } 31 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/Sleeper.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | /** 24 | * Mostly for testing. An interface that represents a thread sleeping. 25 | */ 26 | public interface Sleeper { 27 | void sleep(long millis) throws InterruptedException; 28 | } 29 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/coordination/NodeUpdater.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.coordination; 22 | 23 | import java.io.IOException; 24 | 25 | public interface NodeUpdater { 26 | 27 | boolean update(byte[] bytes) throws IOException; 28 | } 29 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/descriptors/Goal.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common.descriptors; 22 | 23 | /** 24 | * An enum representing a Job Goal. That is: what would we like to do to the job? 25 | */ 26 | public enum Goal { 27 | START, 28 | STOP, 29 | UNDEPLOY 30 | } 31 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/descriptors/JobIdParseException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common.descriptors; 22 | 23 | public class JobIdParseException extends Exception { 24 | 25 | public JobIdParseException(final String message) { 26 | super(message); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/RetryIntervalPolicy.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | /** 24 | * Provides retry schedulers. See {@link BoundedRandomExponentialBackoff}. 25 | */ 26 | public interface RetryIntervalPolicy { 27 | 28 | RetryScheduler newScheduler(); 29 | } 30 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/MetricsContext.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | public interface MetricsContext { 24 | 25 | public void success(); 26 | 27 | public void failure(); 28 | 29 | public void userError(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/descriptors/ThrottleState.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common.descriptors; 22 | 23 | // If you edit this, you'll want to do something reasonable in RestartPolicy 24 | public enum ThrottleState { 25 | NO, 26 | FLAPPING, 27 | IMAGE_MISSING, 28 | IMAGE_PULL_FAILED, 29 | } 30 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/HealthChecker.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | import com.spotify.docker.client.exceptions.DockerException; 24 | 25 | public interface HealthChecker { 26 | public boolean check(String containerId) 27 | throws InterruptedException, DockerException; 28 | } 29 | -------------------------------------------------------------------------------- /helios-service-registration/src/main/java/com/spotify/helios/serviceregistration/NopServiceRegistrationHandle.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Service Registration 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.serviceregistration; 22 | 23 | /** 24 | * A nop service registration handle. 25 | */ 26 | public class NopServiceRegistrationHandle implements ServiceRegistrationHandle { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /helios-testing-common/src/main/resources/META-INF/services/com.spotify.helios.serviceregistration.ServiceRegistrarFactory: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2014 Spotify AB. 3 | # 4 | # Licensed to the Apache Software Foundation (ASF) under one 5 | # or more contributor license agreements. See the NOTICE file 6 | # distributed with this work for additional information 7 | # regarding copyright ownership. The ASF licenses this file 8 | # to you under the Apache License, Version 2.0 (the 9 | # "License"); you may not use this file except in compliance 10 | # with the License. You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, 15 | # software distributed under the License is distributed on an 16 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | # KIND, either express or implied. See the License for the 18 | # specific language governing permissions and limitations 19 | # under the License. 20 | # 21 | 22 | com.spotify.helios.MockServiceRegistrarFactory -------------------------------------------------------------------------------- /solo/helios-env: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "x$DOCKER_HOST" == "x" ]; then 4 | # On Linux, assume DOCKER_HOST is the unix socket. On other platforms, if an 5 | # arbitrary `docker` CLI command can be run, then we can also assume that the 6 | # daemon is listening on the unix socket (or else the docker CLI would not 7 | # work) 8 | if [ "$(uname -s)" == "Linux" ] || docker info >/dev/null 2>&1; then 9 | DOCKER_HOST=unix:///var/run/docker.sock 10 | echo export DOCKER_HOST=$DOCKER_HOST 11 | else 12 | echo "DOCKER_HOST needs to be set" 13 | exit 1 14 | fi 15 | fi 16 | 17 | 18 | if [[ "$DOCKER_HOST" == unix:///* ]]; then 19 | DOCKER_HOST_RAW=localhost 20 | DOCKER_HOST_ADDRESS=127.0.0.1 21 | else 22 | DOCKER_HOST_RAW=$(echo $DOCKER_HOST | sed 's/^[a-zA-Z]\{1,\}:\/\///') 23 | DOCKER_HOST_ADDRESS=$(echo $DOCKER_HOST_RAW | cut -d: -f1) 24 | fi 25 | HELIOS_URI=http://$DOCKER_HOST_ADDRESS:5801 26 | 27 | echo export DOCKER_HOST_RAW=$DOCKER_HOST_RAW 28 | echo export DOCKER_HOST_ADDRESS=$DOCKER_HOST_ADDRESS 29 | echo export HELIOS_URI=$HELIOS_URI 30 | -------------------------------------------------------------------------------- /helios-service-registration/src/main/java/com/spotify/helios/serviceregistration/ServiceRegistrationHandle.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Service Registration 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.serviceregistration; 22 | 23 | /** 24 | * A handle representing a service registration. Used with a {@link ServiceRegistrar}. 25 | */ 26 | public interface ServiceRegistrationHandle { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /bin/helios-initialize-acl: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | args=() 4 | dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 5 | 6 | if [[ -e "$dir/../helios-services" ]]; then 7 | jar="$(ls -t $dir/../helios-services/target/helios*-shaded.jar | grep -v sources | grep -v javadoc | head -n 1)" 8 | CLASSPATH="$(cd $(dirname $jar) && pwd -P)/$(basename $jar)" 9 | echo "running in helios project, using $CLASSPATH" 1>&2 10 | else 11 | CLASSPATH="/usr/share/helios/lib/services/*" 12 | fi 13 | 14 | DEBUG_ARGS="" 15 | if [[ -n "$JDWPPORT" ]]; then 16 | # suspend=n doesn't make much sense as the helios CLI command might finish 17 | # before you start and attach the debugger 18 | DEBUG_ARGS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=$JDWPPORT" 19 | fi 20 | 21 | exec java \ 22 | $DEBUG_ARGS \ 23 | "${args[@]}" \ 24 | -Djava.net.preferIPv4Stack=true \ 25 | -XX:+TieredCompilation -XX:TieredStopAtLevel=1 \ 26 | -Xverify:none \ 27 | -cp "$CLASSPATH" \ 28 | com.spotify.helios.servicescommon.ZooKeeperAclInitializer \ 29 | "$@" 30 | -------------------------------------------------------------------------------- /docs/event_senders.md: -------------------------------------------------------------------------------- 1 | Helios Event Senders 2 | === 3 | 4 | There is support to send events on Helios cluster updates. 5 | 6 | From helios masters, the following events are sent: 7 | 8 | Topic `HeliosDeploymentGroupEvents` with a `DeploymentGroupEvent` message, 9 | see `com.spotify.helios.rollingupdate.DeploymentGroupEventFactory`. 10 | 11 | From helios agents: 12 | 13 | Topic `HeliosTaskStatusEvents` with a `HeliosTaskStatusEvent` message, 14 | see `com.spotify.helios.common.descriptors.TaskStatusEvent`. 15 | 16 | 17 | There is support to send events over Kafka, and over Google PubSub. 18 | 19 | 20 | Kafka 21 | --- 22 | 23 | Using the command line argument `--kafka `, Kafka publishing is enabled. The Kafka sender creates a KafkaRecord from the 24 | topic and message as is. 25 | 26 | GooglePubSub 27 | --- 28 | 29 | Using the command line argument `--pubsub-topic-prefix `, Google PubSub publishing is enabled. The Google PubSub sender 30 | concatenates the topic prefix with the the helios event topic (with no separator), and sends the message as payload. 31 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/coordination/ZooKeeperOperation.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.coordination; 22 | 23 | import org.apache.curator.framework.api.transaction.CuratorTransaction; 24 | 25 | public interface ZooKeeperOperation { 26 | void register(CuratorTransaction transaction) throws Exception; 27 | } 28 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | Helios Documentation 2 | -------------------- 3 | 4 | * **[User Manual](user_manual.md)**
5 | How to create and deploy jobs in a Helios cluster. 6 | 7 | * **[Using helios-solo](helios_solo.md)**
8 | Use helios-solo to start a local Helios cluster in a Docker container. 9 | 10 | * **[Deploying Helios](how_to_deploy.md)**
11 | How to setup and install a real Helios cluster. 12 | 13 | * **[Helios Testing Framework](testing_framework.md)**
14 | How to write JUnit integration tests to spin up (dependent) containers so you can run tests against them. 15 | 16 | * **[Simplified Master Lookup](automatic_master_lookup.md)**
17 | Don't want to type `helios -z http://foo.bar:5801`, but rather something more like `helios -d prod` or `-d testing`? Then read this. 18 | 19 | * **[Registering Containers with Service Discovery](service_registration.md)** 20 | Everything you wanted to know about how to use Helios and whatever service discovery system you have. 21 | 22 | * **[Authentication](authentication.md)** 23 | Client to backend authentication. 24 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/ThreadSleeper.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | /** 24 | * An implementation of {@link Sleeper} that calls Thread.sleep(). 25 | */ 26 | public class ThreadSleeper implements Sleeper { 27 | @Override 28 | public void sleep(long millis) throws InterruptedException { 29 | Thread.sleep(millis); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/SystemClock.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common; 22 | 23 | import org.joda.time.Instant; 24 | 25 | /** 26 | * An implementation of {@link Clock} that returns current system time. 27 | */ 28 | public class SystemClock implements Clock { 29 | 30 | @Override 31 | public Instant now() { 32 | return new Instant(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/Metrics.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | public interface Metrics { 24 | 25 | void start(); 26 | 27 | void stop(); 28 | 29 | MasterMetrics getMasterMetrics(); 30 | 31 | SupervisorMetrics getSupervisorMetrics(); 32 | 33 | ZooKeeperMetrics getZooKeeperMetrics(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/NoopMetricsContext.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | public class NoopMetricsContext implements MetricsContext { 24 | 25 | @Override 26 | public void success() {} 27 | 28 | @Override 29 | public void failure() {} 30 | 31 | @Override 32 | public void userError() {} 33 | 34 | } 35 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/Version.java.template: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Spotify AB. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, 11 | * software distributed under the License is distributed on an 12 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 13 | * KIND, either express or implied. See the License for the 14 | * specific language governing permissions and limitations 15 | * under the License. 16 | */ 17 | 18 | package com.spotify.helios.common; 19 | 20 | // This is a generated file from Version.java.template 21 | // EDITS TO THIS FILE WILL BE LOST 22 | public final class Version { 23 | 24 | public static final String POM_VERSION = "@pomversion@"; 25 | 26 | // TODO (drewc): This should be manually maintained once we get to 1.0 27 | public static final String RECOMMENDED_VERSION = "@pomversion@"; 28 | } 29 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/ReactorFactory.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon; 22 | 23 | import static com.spotify.helios.servicescommon.Reactor.Callback; 24 | 25 | public class ReactorFactory { 26 | 27 | public Reactor create(final String name, final Callback callback, final long timeout) { 28 | return new DefaultReactor(name, callback, timeout); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/resources/RequestUser.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master.resources; 22 | 23 | import java.lang.annotation.ElementType; 24 | import java.lang.annotation.Retention; 25 | import java.lang.annotation.RetentionPolicy; 26 | import java.lang.annotation.Target; 27 | 28 | @Target({ ElementType.PARAMETER }) 29 | @Retention(RetentionPolicy.RUNTIME) 30 | public @interface RequestUser {} 31 | -------------------------------------------------------------------------------- /helios-tools/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | 20 | 21 | 22 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /helios-system-tests/src/main/resources/agent-upgrades-task-file-test/task-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "/config/hosts/test-host/jobs/test_16c903a4foo1:test_17:daac0009225685ae214784a73b184c254c6353fb": "eyJqb2IiOnsiaWQiOiJ0ZXN0XzE2YzkwM2E0Zm9vMTp0ZXN0XzE3OmRhYWMwMDA5MjI1Njg1YWUyMTQ3ODRhNzNiMTg0YzI1NGM2MzUzZmIiLCJpbWFnZSI6ImJ1c3lib3giLCJjb21tYW5kIjpbInNoIiwiLWMiLCJ3aGlsZSA6OyBkbyBzbGVlcCAxOyBkb25lIl0sImVudiI6e30sInBvcnRzIjp7ImJhciI6eyJpbnRlcm5hbFBvcnQiOjQ3MTIsImV4dGVybmFsUG9ydCI6MzIwMzksInByb3RvY29sIjoidGNwIn0sImZvbyI6eyJpbnRlcm5hbFBvcnQiOjQ3MTEsImV4dGVybmFsUG9ydCI6bnVsbCwicHJvdG9jb2wiOiJ0Y3AifX0sInJlZ2lzdHJhdGlvbiI6e319LCJnb2FsIjoiU1RBUlQifQ==", 3 | "/config/hosts/test-host/jobs/test_16c903a4foo2:test_17:62ae5f8a10e7bf3427dfd0ae7498a3f09abc0bd6": "eyJqb2IiOnsiaWQiOiJ0ZXN0XzE2YzkwM2E0Zm9vMjp0ZXN0XzE3OjYyYWU1ZjhhMTBlN2JmMzQyN2RmZDBhZTc0OThhM2YwOWFiYzBiZDYiLCJpbWFnZSI6ImJ1c3lib3giLCJjb21tYW5kIjpbInNoIiwiLWMiLCJ3aGlsZSA6OyBkbyBzbGVlcCAxOyBkb25lIl0sImVudiI6e30sInBvcnRzIjp7ImJhciI6eyJpbnRlcm5hbFBvcnQiOjQ3MTIsImV4dGVybmFsUG9ydCI6MzA1ODMsInByb3RvY29sIjoidGNwIn0sImZvbyI6eyJpbnRlcm5hbFBvcnQiOjQ3MTEsImV4dGVybmFsUG9ydCI6bnVsbCwicHJvdG9jb2wiOiJ0Y3AifX0sInJlZ2lzdHJhdGlvbiI6e319LCJnb2FsIjoiU1RBUlQifQ==" 4 | } 5 | -------------------------------------------------------------------------------- /src/deb/helios-master/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ "$1" = configure ]; then 3 | # Make sure the helios user exists 4 | if ! getent passwd helios > /dev/null; then 5 | adduser --system --quiet --home /var/lib/helios-master --no-create-home \ 6 | --shell /bin/bash --group --gecos "Helios" helios 7 | fi 8 | 9 | # check validity of helios user and group 10 | if [ "`id -u helios`" -eq 0 ]; then 11 | echo "The helios user must not have uid 0 (root). 12 | Please fix this and reinstall this package." >&2 13 | exit 1 14 | fi 15 | if [ "`id -g helios`" -eq 0 ]; then 16 | echo "The helios user must not have root as primary group. 17 | Please fix this and reinstall this package." >&2 18 | exit 1 19 | fi 20 | fi 21 | 22 | # Start helios-master 23 | if which initctl >/dev/null && initctl version | grep -q upstart; then 24 | # Using upstart 25 | initctl stop helios-master >/dev/null 2>&1 || true 26 | initctl start helios-master || true 27 | else 28 | # Using SysV init scripts 29 | /etc/init.d/helios-master stop >/dev/null 2>&1 || true 30 | /etc/init.d/helios-master start || true 31 | fi 32 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/MasterMetrics.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | public interface MasterMetrics { 24 | 25 | void success(String name); 26 | 27 | void failure(String name); 28 | 29 | void badRequest(String name); 30 | 31 | void clientVersion(String version); 32 | 33 | void jobsInJobList(int count); 34 | 35 | void jobsHistoryEventSize(int count); 36 | } 37 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/HeliosException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common; 22 | 23 | public class HeliosException extends Exception { 24 | 25 | public HeliosException(final String message) { 26 | super(message); 27 | } 28 | 29 | public HeliosException(final Throwable cause) { 30 | super(cause); 31 | } 32 | 33 | public HeliosException(final String message, final Throwable cause) { 34 | super(message, cause); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/rollingupdate/RolloutPlanner.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.rollingupdate; 22 | 23 | import com.spotify.helios.common.descriptors.RolloutTask; 24 | import java.util.List; 25 | 26 | public interface RolloutPlanner { 27 | 28 | /** 29 | * Returns a list of {@link RolloutTask}s. 30 | * Caller is responsible for passing in a list of hosts that are up. 31 | */ 32 | List plan(final List hosts); 33 | } 34 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/JobAlreadyDeployedException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master; 22 | 23 | import com.spotify.helios.common.HeliosException; 24 | import com.spotify.helios.common.descriptors.JobId; 25 | 26 | public class JobAlreadyDeployedException extends HeliosException { 27 | 28 | public JobAlreadyDeployedException(String host, JobId job) { 29 | super(String.format("Job [%s] already deployed on host [%s]", host, job)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/client/RequestDispatcher.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.client; 22 | 23 | import com.google.common.util.concurrent.ListenableFuture; 24 | import java.io.Closeable; 25 | import java.net.URI; 26 | import java.util.List; 27 | import java.util.Map; 28 | 29 | interface RequestDispatcher extends Closeable { 30 | 31 | ListenableFuture request( 32 | URI uri, String method, byte[] entityBytes, Map> headers); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /helios-testing/src/test/resources/helios-base.conf: -------------------------------------------------------------------------------- 1 | #Overridden by the helios.conf, so this tests overriding works properly 2 | helios.testing.profile : "some totally bogus profile" 3 | helios.testing.profiles : { 4 | 5 | local : { 6 | image : "spotify/busybox:latest" 7 | hostFilter : ".*" 8 | env : { 9 | SPOTIFY_TEST_THING: "See, we used the prefix here -->"${prefix}"<--" 10 | SPOTIFY_DOMAIN: ${prefix}".local." 11 | SPOTIFY_POD: ${prefix}".local." 12 | } 13 | } 14 | 15 | helios-ci: { 16 | image: "spotify/busybox:latest" 17 | domain: "shared.cloud.spotify.net" 18 | hostFilter: ".+\\.helios-ci\\.cloud" 19 | deployTimeoutMillis: 120000 20 | env: { 21 | SPOTIFY_DOMAIN: ${prefix}".services.helios-ci.cloud.spotify.net" 22 | SPOTIFY_POD: ${prefix}".services.helios-ci.cloud.spotify.net" 23 | SPOTIFY_SYSLOG_HOST: 10.99.0.1 24 | } 25 | } 26 | } 27 | 28 | #Overridden by the helios.conf, so this tests overriding works properly 29 | helios.solo.profile : "some totally bogus profile" 30 | helios.solo.profiles : { 31 | 32 | local : { 33 | env : { 34 | REGISTRAR_HOST_FORMAT: "_${service}._${protocol}.services.${domain}" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /helios-services/src/main/resources/master-banner.txt: -------------------------------------------------------------------------------- 1 | _____ 2 | __ __ _____\ \ _____ ____________ ____ _____ 3 | / \ / \ / / | ||\ \ / \ ____\_ \__ _____\ \ 4 | / /| |\ \ / / /___/| \\ \ |\___/\ \\___/| / / \ / / \ | 5 | / // \\ \ | |__ |___|/ \\ \ \|____\ \___|// /\ | | | /___/| 6 | / \_____/ \ | \ \| | ______ | | | | | | ____\ \ | || 7 | / /\_____/\ \ | __/ __ | |/ \ __ / / __ | | | | / /\ \|___|/ 8 | / //\_____/\\ \ |\ \ / \ / | / \/ /_/ || | / /|| |/ \ \ 9 | /____/ | | \____\| \____\/ | /_____/\_____/||____________/||\ \_____/ ||\____\ /____/| 10 | | | | | | || | |____/| | | | ||| | /| \_____\ | / | | || | | 11 | |____|/ \|____| \|____| | | |______|/|____|/|___________|/ \ | |___|/ \|___||____|/ 12 | |___|/ \|____| 13 | -------------------------------------------------------------------------------- /helios-testing/src/main/java/com/spotify/helios/testing/HeliosDeploymentException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.testing; 22 | 23 | public class HeliosDeploymentException extends Exception { 24 | 25 | public HeliosDeploymentException(final String message) { 26 | super(message); 27 | } 28 | 29 | public HeliosDeploymentException(final Throwable cause) { 30 | super(cause); 31 | } 32 | 33 | public HeliosDeploymentException(final String message, final Throwable cause) { 34 | super(message, cause); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /helios-service-registration/src/main/java/com/spotify/helios/serviceregistration/ServiceRegistrarLoadingException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Service Registration 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.serviceregistration; 22 | 23 | import java.util.ServiceConfigurationError; 24 | 25 | /** 26 | * Indicates that an error occurred during service registrar plugin loading. 27 | */ 28 | public class ServiceRegistrarLoadingException extends Exception { 29 | 30 | ServiceRegistrarLoadingException(final String message, final ServiceConfigurationError err) { 31 | super(message, err); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/JobExistsException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master; 22 | 23 | import com.spotify.helios.common.HeliosException; 24 | 25 | public class JobExistsException extends HeliosException { 26 | 27 | public JobExistsException(final String message) { 28 | super(message); 29 | } 30 | 31 | public JobExistsException(final Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | public JobExistsException(final String message, final Throwable cause) { 36 | super(message, cause); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/Hash.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common; 22 | 23 | import java.security.MessageDigest; 24 | import java.security.NoSuchAlgorithmException; 25 | 26 | public class Hash { 27 | 28 | public static byte[] sha1digest(final byte[] bytes) { 29 | return sha1().digest(bytes); 30 | } 31 | 32 | public static MessageDigest sha1() { 33 | try { 34 | return MessageDigest.getInstance("SHA-1"); 35 | } catch (NoSuchAlgorithmException e) { 36 | throw new RuntimeException(e); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/rollingupdate/RollingUpdateError.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.rollingupdate; 22 | 23 | public enum RollingUpdateError { 24 | PORT_CONFLICT, 25 | JOB_UNEXPECTEDLY_UNDEPLOYED, 26 | JOB_ALREADY_DEPLOYED, 27 | TIMED_OUT_WAITING_FOR_JOB_TO_REACH_RUNNING, 28 | TIMED_OUT_WAITING_FOR_JOB_TO_UNDEPLOY, 29 | UNABLE_TO_MARK_HOST_UNDEPLOYED, 30 | TOKEN_VERIFICATION_ERROR, 31 | JOB_NOT_FOUND, 32 | HOST_NOT_FOUND, 33 | TIMED_OUT_RETRIEVING_JOB_STATUS, 34 | IMAGE_MISSING, 35 | IMAGE_PULL_FAILED, 36 | UNKNOWN 37 | } 38 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/HostNotFoundException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master; 22 | 23 | import com.spotify.helios.common.HeliosException; 24 | 25 | public class HostNotFoundException extends HeliosException { 26 | 27 | public HostNotFoundException(final String message) { 28 | super(message); 29 | } 30 | 31 | public HostNotFoundException(final Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | public HostNotFoundException(final String message, final Throwable cause) { 36 | super(message, cause); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /findbugs-exclude.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /helios-tools/src/main/java/com/spotify/helios/cli/command/CliCommand.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Tools 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.cli.command; 22 | 23 | import com.spotify.helios.cli.Target; 24 | import java.io.BufferedReader; 25 | import java.io.PrintStream; 26 | import java.util.List; 27 | import net.sourceforge.argparse4j.inf.Namespace; 28 | 29 | public interface CliCommand { 30 | int run(final Namespace options, final List targets, final PrintStream out, 31 | final PrintStream err, final String username, final boolean json, 32 | final BufferedReader stdin) 33 | throws Exception; 34 | } 35 | -------------------------------------------------------------------------------- /docs/developer_guide.md: -------------------------------------------------------------------------------- 1 | # Building Helios and Running Tests 2 | 3 | 1. Under the parent level helios source directory run `mvn clean install`. This will run the integration tests. To avoid running the tests, add the `-DskipTests` option. 4 | 2. Note that the above build command will produce a generate directory under `helios-client/target/generated-sources/templated` which may need to be added as a source directory to your IDE manually. 5 | 3. In order to run the Helios integration tests, first run: `mvn -P build-images -P build-solo package -DskipTests=true -Dmaven.javadoc.skip=true -B -V -pl helios-services`. 6 | 7 | Use `bin/helios` and `bin/helios-master` to start the Helios CLI and server 8 | (respectively) from the locally-built project. 9 | 10 | ## Running helios-system-tests locally 11 | 12 | If you are running helios-system-tests locally and are wondering where the 13 | slf4j/logback output is when the tests are being run, SystemTestBase will by 14 | default configure logback to be extra verbose and [to write 15 | logs][LoggingTestWatcher] to `/tmp/helios-test/log/`. 16 | 17 | This behavior can be disabled by disabling the `logToFile` system property when 18 | maven-surefire-plugin is invoked. 19 | 20 | [LoggingTestWatcher]: ../helios-system-tests/src/main/java/com/spotify/helios/system/LoggingTestWatcher.java 21 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/http/PATCH.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master.http; 22 | 23 | import java.lang.annotation.ElementType; 24 | import java.lang.annotation.Retention; 25 | import java.lang.annotation.RetentionPolicy; 26 | import java.lang.annotation.Target; 27 | import javax.ws.rs.HttpMethod; 28 | 29 | /** 30 | * So we can do @PATCH, like we do @GET or @POST. 31 | */ 32 | @SuppressWarnings("AbbreviationAsWordInName") 33 | @Target({ ElementType.METHOD }) 34 | @Retention(RetentionPolicy.RUNTIME) 35 | @HttpMethod("PATCH") 36 | public @interface PATCH { 37 | } 38 | -------------------------------------------------------------------------------- /helios-service-registration/src/main/java/com/spotify/helios/serviceregistration/NopServiceRegistrarFactory.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Service Registration 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.serviceregistration; 22 | 23 | /** 24 | * A factory for nop service registrars. 25 | */ 26 | public class NopServiceRegistrarFactory implements ServiceRegistrarFactory { 27 | 28 | @Override 29 | public ServiceRegistrar create(final String address) { 30 | return new NopServiceRegistrar(); 31 | } 32 | 33 | @Override 34 | public ServiceRegistrar createForDomain(final String domain) { 35 | return new NopServiceRegistrar(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/coordination/ZooKeeperNodeUpdaterFactory.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.coordination; 22 | 23 | 24 | public class ZooKeeperNodeUpdaterFactory implements NodeUpdaterFactory { 25 | 26 | final ZooKeeperClient zooKeeperClient; 27 | 28 | public ZooKeeperNodeUpdaterFactory(final ZooKeeperClient zooKeeperClient) { 29 | this.zooKeeperClient = zooKeeperClient; 30 | } 31 | 32 | @Override 33 | public ZooKeeperNodeUpdater create(final String path) { 34 | return new ZooKeeperNodeUpdater(path, zooKeeperClient); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/coordination/ZooKeeperClientProvider.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.coordination; 22 | 23 | public class ZooKeeperClientProvider { 24 | private final ZooKeeperClient client; 25 | private final ZooKeeperModelReporter reporter; 26 | 27 | public ZooKeeperClientProvider(ZooKeeperClient client, ZooKeeperModelReporter reporter) { 28 | this.client = client; 29 | this.reporter = reporter; 30 | } 31 | 32 | public ZooKeeperClient get(String tag) { 33 | return new ReportingZooKeeperClient(client, reporter, tag); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/Reactor.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon; 22 | 23 | import com.google.common.util.concurrent.Service; 24 | 25 | public interface Reactor extends Service { 26 | 27 | interface Callback { 28 | void run(boolean timeout) throws InterruptedException; 29 | } 30 | 31 | /** 32 | * Send a signal to trigger the reactor. Does not block. 33 | */ 34 | void signal(); 35 | 36 | /** 37 | * Returns a runnable that calls {@link #signal()}. 38 | * 39 | * @return The runnable object. 40 | */ 41 | Runnable signalRunnable(); 42 | } 43 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/DeploymentGroupExistsException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master; 22 | 23 | import com.spotify.helios.common.HeliosException; 24 | 25 | public class DeploymentGroupExistsException extends HeliosException { 26 | 27 | public DeploymentGroupExistsException(final String message) { 28 | super(message); 29 | } 30 | 31 | public DeploymentGroupExistsException(final Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | public DeploymentGroupExistsException(final String message, final Throwable cause) { 36 | super(message, cause); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/NoopZooKeeperMetrics.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | import java.util.concurrent.TimeUnit; 24 | import org.apache.curator.framework.state.ConnectionState; 25 | 26 | public class NoopZooKeeperMetrics implements ZooKeeperMetrics { 27 | @Override 28 | public void zookeeperTransientError() {} 29 | 30 | @Override 31 | public void updateTimer(String name, long duration, TimeUnit timeUnit) { 32 | } 33 | 34 | @Override 35 | public void connectionStateChanged(final ConnectionState newState) { 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/RetryScheduler.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | public interface RetryScheduler { 24 | 25 | /** 26 | * Get the current interval. Updated when {@link #nextMillis()} is called. 27 | * 28 | * @return The current interval in milliseconds. 29 | */ 30 | long currentMillis(); 31 | 32 | /** 33 | * Progress to and return a new interval. {@link #currentMillis()} will return this interval until 34 | * the next invocation of {@link #nextMillis()}. 35 | * 36 | * @return The new interval in milliseconds. 37 | */ 38 | long nextMillis(); 39 | } 40 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/DeploymentGroupDoesNotExistException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master; 22 | 23 | import com.spotify.helios.common.HeliosException; 24 | 25 | public class DeploymentGroupDoesNotExistException extends HeliosException { 26 | 27 | public DeploymentGroupDoesNotExistException(final String message) { 28 | super(message); 29 | } 30 | 31 | public DeploymentGroupDoesNotExistException(final Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | public DeploymentGroupDoesNotExistException(final String message, final Throwable cause) { 36 | super(message, cause); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/UIDCACert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDgDCCAmigAwIBAgICA+kwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCVVMx 3 | HzAdBgNVBAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExFTATBgNVBAMTDFRydXN0 4 | IEFuY2hvcjAeFw0xMDAxMDEwODMwMDBaFw0zMDEyMzEwODMwMDBaMD8xCzAJBgNV 5 | BAYTAlVTMR8wHQYDVQQKExZUZXN0IENlcnRpZmljYXRlcyAyMDExMQ8wDQYDVQQD 6 | EwZVSUQgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCeFABwDBUn 7 | ApJRGeo/+64E11KZ3rpoF+VJIX9apBq3DmF5GxhYb5PiFTkOPLN34PwLf3qLez93 8 | SSgZv/lXeQhWnudJlYLTwyHleDYo6uzFzG97ud10DKLEL4qz6tsNmgOFN7DUsARW 9 | cniQeA+PlB7FOAq+Np3AU3thtysN9pj/7kfthiHSpnaolauqdQFug2QC/Tsuqlpb 10 | wdZmC+0jcjz6F7FPOSo/dkTb1gy04sjoA6QRuCAskjlkQvSuviU48CYZwlXJg87m 11 | R6t5yDk1kv1NSUcL0g7PNC/yIMZiNKzkP+hVOYc/EK8dJv2u8rmp74xCW7Zq6lhe 12 | jgZF27pmsTuLAgMBAAGCAgUgo3wwejAfBgNVHSMEGDAWgBTkfV/RXJWGCCwFrr51 13 | tmWn2V2oZjAdBgNVHQ4EFgQUED/FBDDx2EM2hXlcjI2Lne4vHKkwDgYDVR0PAQH/ 14 | BAQDAgEGMBcGA1UdIAQQMA4wDAYKYIZIAWUDAgEwATAPBgNVHRMBAf8EBTADAQH/ 15 | MA0GCSqGSIb3DQEBCwUAA4IBAQALOuCe7LwozytIfL3W2cNZdLVrhfOXpE/spkte 16 | 1wi3VLrPYFYX/WMaoL++FBP2Ct3vMRaAmBHeAScN+FYPXP5Nc4DUiDlDXIC7oHJa 17 | BFlZq50K9sUIfDUiH2acsdrNqwh6QRO5+tdah+kNRmSnq1x+b/gSVkruCyo/hgLe 18 | XuvjLlB9CHf7FcD2TjT6kVHwTztZVOyC3PD0itzmla8BiY+Bx27Mmhk9ivQLeM/l 19 | ZXScBDdjrKanYIqmcvdrHGVRjBzpMQE/Vq7wwb9pDsm0nUiaHcfJQxrzNOlIsov6 20 | jtBJCP2luvGQia/7gwP8r6Ft2SsgMqH59wBxSipXP3qpz6sS 21 | -----END CERTIFICATE----- -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/VersionedValue.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon; 22 | 23 | public class VersionedValue { 24 | 25 | private final T value; 26 | private final int version; 27 | 28 | public static VersionedValue of(final T value, int version) { 29 | return new VersionedValue<>(value, version); 30 | } 31 | 32 | public VersionedValue(final T value, final int version) { 33 | this.value = value; 34 | this.version = version; 35 | } 36 | 37 | public T value() { 38 | return value; 39 | } 40 | 41 | public int version() { 42 | return version; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /helios-testing/src/main/java/com/spotify/helios/testing/Deployer.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.testing; 22 | 23 | import com.spotify.helios.common.descriptors.Job; 24 | import java.util.List; 25 | import java.util.Set; 26 | 27 | public interface Deployer { 28 | 29 | TemporaryJob deploy(Job job, List hosts, Set waitPorts, Prober prober, 30 | TemporaryJobReports.ReportWriter reportWriter); 31 | 32 | TemporaryJob deploy(Job job, String hostFilter, Set waitPorts, Prober prober, 33 | TemporaryJobReports.ReportWriter reportWriter); 34 | 35 | void readyToDeploy(); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/NoopMasterMetrics.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | public class NoopMasterMetrics implements MasterMetrics { 24 | 25 | @Override 26 | public void success(final String name) {} 27 | 28 | @Override 29 | public void failure(final String name) {} 30 | 31 | @Override 32 | public void badRequest(final String name) {} 33 | 34 | @Override 35 | public void clientVersion(final String version) {} 36 | 37 | @Override 38 | public void jobsInJobList(int count) {} 39 | 40 | @Override 41 | public void jobsHistoryEventSize(int count) {} 42 | } 43 | -------------------------------------------------------------------------------- /helios-service-registration/src/main/java/com/spotify/helios/serviceregistration/NopServiceRegistrar.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Service Registration 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.serviceregistration; 22 | 23 | /** 24 | * A nop service registrar that does nothing. Useful as an alternative to null. 25 | */ 26 | public class NopServiceRegistrar implements ServiceRegistrar { 27 | 28 | @Override 29 | public ServiceRegistrationHandle register(final ServiceRegistration registration) { 30 | return new NopServiceRegistrationHandle(); 31 | } 32 | 33 | @Override 34 | public void unregister(final ServiceRegistrationHandle handle) { 35 | } 36 | 37 | @Override 38 | public void close() { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/NoopMetrics.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | public class NoopMetrics implements Metrics { 24 | 25 | @Override 26 | public void start() {} 27 | 28 | @Override 29 | public void stop() {} 30 | 31 | @Override 32 | public MasterMetrics getMasterMetrics() { 33 | return new NoopMasterMetrics(); 34 | } 35 | 36 | @Override 37 | public SupervisorMetrics getSupervisorMetrics() { 38 | return new NoopSupervisorMetrics(); 39 | } 40 | 41 | @Override 42 | public ZooKeeperMetrics getZooKeeperMetrics() { 43 | return new NoopZooKeeperMetrics(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/coordination/Node.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.coordination; 22 | 23 | import org.apache.zookeeper.data.Stat; 24 | 25 | public class Node { 26 | 27 | private final String path; 28 | private final byte[] bytes; 29 | private final Stat stat; 30 | 31 | public Node(final String path, final byte[] bytes, final Stat stat) { 32 | this.path = path; 33 | this.bytes = bytes; 34 | this.stat = stat; 35 | } 36 | 37 | public String getPath() { 38 | return path; 39 | } 40 | 41 | public byte[] getBytes() { 42 | return bytes; 43 | } 44 | 45 | public Stat getStat() { 46 | return stat; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /helios-service-registration/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | com.spotify 7 | helios-parent 8 | 0.9.0-SNAPSHOT 9 | 10 | 11 | Helios Service Registration 12 | helios-service-registration 13 | jar 14 | 15 | 16 | 17 | org.slf4j 18 | slf4j-api 19 | 20 | 21 | com.google.guava 22 | guava 23 | 24 | 25 | 26 | 27 | 28 | org.apache.maven.plugins 29 | maven-source-plugin 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-javadoc-plugin 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /bin/helios: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | # 3 | # Wrapper for running the Helios CLI which will use the locally built `helios` 4 | # if run from the checked-out source code's root directory. 5 | # 6 | # This script will start java with the necessary JDWP arguments to suspend the 7 | # process until a debugger is attached if the `JDWPPORT` environment variable 8 | # is set like `JDWPPORT=5005 helios ...`. 9 | 10 | dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 11 | 12 | if [[ -e "$dir/../helios-tools" ]]; then 13 | jar="$(ls -t $dir/../helios-tools/target/helios-tools*-shaded.jar | grep -v sources | grep -v javadoc | head -n 1)" 14 | CLASSPATH="$(cd $(dirname $jar) && pwd -P)/$(basename $jar)" 15 | echo "running in helios project, using $CLASSPATH" 1>&2 16 | else 17 | CLASSPATH="/usr/share/helios/lib/tools/*" 18 | fi 19 | 20 | DEBUG_ARGS="" 21 | if [[ -n "$JDWPPORT" ]]; then 22 | # suspend=n doesn't make much sense as the helios CLI command might finish 23 | # before you start and attach the debugger 24 | DEBUG_ARGS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=$JDWPPORT" 25 | fi 26 | 27 | export SUPPRESS_GCLOUD_CREDS_WARNING=true 28 | 29 | exec java \ 30 | $JVM_ARGS \ 31 | $DEBUG_ARGS \ 32 | -Djava.net.preferIPv4Stack=true \ 33 | -XX:+TieredCompilation -XX:TieredStopAtLevel=1 \ 34 | -Xverify:none \ 35 | -cp "$CLASSPATH" \ 36 | com.spotify.helios.cli.CliMain \ 37 | "$@" 38 | -------------------------------------------------------------------------------- /helios-testing-common/src/main/resources/logback-access.xml: -------------------------------------------------------------------------------- 1 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/JobNotDeployedException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master; 22 | 23 | import com.spotify.helios.common.HeliosException; 24 | import com.spotify.helios.common.descriptors.JobId; 25 | 26 | public class JobNotDeployedException extends HeliosException { 27 | 28 | private final String host; 29 | private final JobId jobId; 30 | 31 | public JobNotDeployedException(String host, JobId jobId) { 32 | super(String.format("Job [%s] is not deployed on host [%s]", jobId, host)); 33 | this.host = host; 34 | this.jobId = jobId; 35 | } 36 | 37 | public String getHost() { 38 | return host; 39 | } 40 | 41 | public JobId getJobId() { 42 | return jobId; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/client/HttpConnector.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.client; 22 | 23 | import com.spotify.helios.common.HeliosException; 24 | import java.io.Closeable; 25 | import java.net.HttpURLConnection; 26 | import java.net.URI; 27 | import java.util.List; 28 | import java.util.Map; 29 | 30 | interface HttpConnector extends Closeable { 31 | 32 | // TODO (mbrown): it's ugly that this has the same list of parameters as RequestDispatcher 33 | // TODO (mbrown): should create a Request interface instead to hold all of them 34 | HttpURLConnection connect(final URI uri, final String method, final byte[] entity, 35 | final Map> headers) throws HeliosException; 36 | } 37 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/StatusUpdater.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | import com.spotify.helios.common.descriptors.Goal; 24 | import com.spotify.helios.common.descriptors.TaskStatus; 25 | import com.spotify.helios.common.descriptors.ThrottleState; 26 | 27 | /** 28 | * An interface used to abstract how task statuses are reported. 29 | */ 30 | public interface StatusUpdater { 31 | 32 | void setThrottleState(ThrottleState throttleState); 33 | 34 | void setContainerId(String containerId); 35 | 36 | void setState(final TaskStatus.State status); 37 | 38 | void setGoal(Goal goal); 39 | 40 | void setContainerError(String containerError); 41 | 42 | void update() throws InterruptedException; 43 | } 44 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/KafkaRecord.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon; 22 | 23 | /** 24 | * This class represents a Kafka record whose data is an array of bytes. 25 | */ 26 | public class KafkaRecord { 27 | 28 | private final String topic; 29 | private final byte[] data; 30 | 31 | private KafkaRecord(final String topic, final byte[] data) { 32 | this.topic = topic; 33 | this.data = data; 34 | } 35 | 36 | public String getKafkaTopic() { 37 | return topic; 38 | } 39 | 40 | public byte[] getKafkaData() { 41 | return data; 42 | } 43 | 44 | public static KafkaRecord of(final String topic, final byte[] data) { 45 | return new KafkaRecord(topic, data); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/JobStillDeployedException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master; 22 | 23 | import com.spotify.helios.common.HeliosException; 24 | import com.spotify.helios.common.descriptors.JobId; 25 | import java.util.List; 26 | 27 | public class JobStillDeployedException extends HeliosException { 28 | 29 | private final JobId id; 30 | private final List hosts; 31 | 32 | public JobStillDeployedException(JobId id, List hosts) { 33 | super(String.format("job %s still deployed on hosts %s", id, hosts)); 34 | this.id = id; 35 | this.hosts = hosts; 36 | } 37 | 38 | public JobId getId() { 39 | return id; 40 | } 41 | 42 | public List getHosts() { 43 | return hosts; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /helios-testing/src/test/java/com/spotify/helios/testing/TemporaryJobsBuilderTest.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.testing; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | import com.google.common.collect.ImmutableMap; 26 | import java.util.Map; 27 | import org.junit.Test; 28 | 29 | public class TemporaryJobsBuilderTest { 30 | 31 | /** 32 | * Ensure that the TemporaryJobs.Builder can be constructed ok when DOCKER_HOST looks like a unix 33 | * socket path. 34 | */ 35 | @Test 36 | public void testDockerHostIsUnixSocket() { 37 | final Map env = ImmutableMap.of("DOCKER_HOST", "unix:///var/run/docker.sock"); 38 | final TemporaryJobs.Builder builder = TemporaryJobs.builder(env); 39 | assertNotNull(builder); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /helios-testing-common/src/main/java/com/spotify/helios/MockServiceRegistrarRegistry.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Common Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios; 22 | 23 | import com.google.common.collect.Maps; 24 | import com.spotify.helios.serviceregistration.ServiceRegistrar; 25 | import java.util.Map; 26 | 27 | public class MockServiceRegistrarRegistry { 28 | private static final Map registrars = Maps.newConcurrentMap(); 29 | 30 | public static void set(final String address, final ServiceRegistrar registrar) { 31 | registrars.put(address, registrar); 32 | } 33 | 34 | public static ServiceRegistrar get(final String address) { 35 | return registrars.get(address); 36 | } 37 | 38 | public static void remove(final String address) { 39 | registrars.remove(address); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/DockerDaemonHealthChecker.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | import com.codahale.metrics.health.HealthCheck; 24 | import com.spotify.docker.client.DockerClient; 25 | 26 | /** 27 | * Checks if helios-agent can talk to Docker daemon. 28 | */ 29 | class DockerDaemonHealthChecker extends HealthCheck { 30 | 31 | private final DockerClient dockerClient; 32 | 33 | DockerDaemonHealthChecker(final DockerClient dockerClient) { 34 | this.dockerClient = dockerClient; 35 | } 36 | 37 | @Override 38 | protected Result check() throws Exception { 39 | try { 40 | dockerClient.ping(); 41 | return Result.healthy(); 42 | } catch (final Exception ex) { 43 | return Result.unhealthy(ex); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/SupervisorMetrics.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | public interface SupervisorMetrics { 24 | 25 | void supervisorStarted(); 26 | 27 | void supervisorStopped(); 28 | 29 | void supervisorClosed(); 30 | 31 | void containersRunning(); 32 | 33 | void containersExited(); 34 | 35 | void containersThrewException(); 36 | 37 | void containerStarted(); 38 | 39 | MetricsContext containerPull(); 40 | 41 | void imageCacheHit(); 42 | 43 | void imageCacheMiss(); 44 | 45 | void dockerTimeout(); 46 | 47 | void supervisorRun(); 48 | 49 | MeterRates getDockerTimeoutRates(); 50 | 51 | MeterRates getContainersThrewExceptionRates(); 52 | 53 | MeterRates getSupervisorRunRates(); 54 | 55 | } 56 | -------------------------------------------------------------------------------- /helios-testing-common/src/main/java/com/spotify/helios/MockServiceRegistrarFactory.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Common Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios; 22 | 23 | import static org.junit.Assert.assertNotNull; 24 | 25 | import com.spotify.helios.serviceregistration.ServiceRegistrar; 26 | import com.spotify.helios.serviceregistration.ServiceRegistrarFactory; 27 | 28 | public class MockServiceRegistrarFactory implements ServiceRegistrarFactory { 29 | 30 | @Override 31 | public ServiceRegistrar create(final String address) { 32 | final ServiceRegistrar registrar = MockServiceRegistrarRegistry.get(address); 33 | assertNotNull(registrar); 34 | return registrar; 35 | } 36 | 37 | @Override 38 | public ServiceRegistrar createForDomain(final String domain) { 39 | throw new UnsupportedOperationException(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/JobDoesNotExistException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master; 22 | 23 | import static java.lang.String.format; 24 | 25 | import com.spotify.helios.common.HeliosException; 26 | import com.spotify.helios.common.descriptors.JobId; 27 | 28 | public class JobDoesNotExistException extends HeliosException { 29 | 30 | public JobDoesNotExistException(final String message) { 31 | super(message); 32 | } 33 | 34 | public JobDoesNotExistException(final Throwable cause) { 35 | super(cause); 36 | } 37 | 38 | public JobDoesNotExistException(final String message, final Throwable cause) { 39 | super(message, cause); 40 | } 41 | 42 | public JobDoesNotExistException(final JobId id) { 43 | super(format("job does not exist: %s", id)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/HostStillInUseException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master; 22 | 23 | import static java.lang.String.format; 24 | 25 | import com.spotify.helios.common.HeliosException; 26 | import com.spotify.helios.common.descriptors.JobId; 27 | import java.util.List; 28 | 29 | public class HostStillInUseException extends HeliosException { 30 | 31 | private final String host; 32 | private final List jobs; 33 | 34 | public HostStillInUseException(final String host, final List jobs) { 35 | super(format("Jobs still deployed on host %s: %s", host, jobs)); 36 | this.host = host; 37 | this.jobs = jobs; 38 | } 39 | 40 | public String getHost() { 41 | return host; 42 | } 43 | 44 | public List getJobs() { 45 | return jobs; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/protocol/JobDeleteResponse.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common.protocol; 22 | 23 | import com.fasterxml.jackson.annotation.JsonProperty; 24 | import com.spotify.helios.common.Json; 25 | 26 | public class JobDeleteResponse { 27 | public enum Status { OK, STILL_IN_USE, JOB_NOT_FOUND, FORBIDDEN } 28 | 29 | private final Status status; 30 | 31 | public JobDeleteResponse(@JsonProperty("status") Status status) { 32 | this.status = status; 33 | } 34 | 35 | public Status getStatus() { 36 | return status; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "JobDeleteResponse{" 42 | + "status=" + status 43 | + '}'; 44 | } 45 | 46 | public String toJsonString() { 47 | return Json.asStringUnchecked(this); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/TokenVerificationException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master; 22 | 23 | import static java.lang.String.format; 24 | 25 | import com.spotify.helios.common.HeliosException; 26 | import com.spotify.helios.common.descriptors.JobId; 27 | 28 | public class TokenVerificationException extends HeliosException { 29 | 30 | public TokenVerificationException(final String message) { 31 | super(message); 32 | } 33 | 34 | public TokenVerificationException(final Throwable cause) { 35 | super(cause); 36 | } 37 | 38 | public TokenVerificationException(final String message, final Throwable cause) { 39 | super(message, cause); 40 | } 41 | 42 | public TokenVerificationException(final JobId id) { 43 | super(format("Token verification failed for job %s", id)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/coordination/ZooKeeperHealthChecker.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.coordination; 22 | 23 | import com.codahale.metrics.health.HealthCheck; 24 | import org.apache.curator.CuratorZookeeperClient; 25 | 26 | public class ZooKeeperHealthChecker extends HealthCheck { 27 | 28 | private final CuratorZookeeperClient client; 29 | 30 | public ZooKeeperHealthChecker(final ZooKeeperClient zooKeeperClient) { 31 | this.client = zooKeeperClient.getCuratorFramework().getZookeeperClient(); 32 | } 33 | 34 | @Override 35 | protected Result check() throws Exception { 36 | if (client.isConnected()) { 37 | return Result.healthy(); 38 | } else { 39 | return Result.unhealthy("CuratorZookeeperClient reports that it is not connected"); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/deb/helios-agent/postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ "$1" = configure ]; then 3 | # Make sure the helios user exists 4 | if ! getent passwd helios > /dev/null; then 5 | adduser --system --quiet --home /var/lib/helios-agent --no-create-home \ 6 | --shell /bin/bash --group --gecos "Helios" helios 7 | fi 8 | 9 | # check validity of helios user and group 10 | if [ "`id -u helios`" -eq 0 ]; then 11 | echo "The helios user must not have uid 0 (root). 12 | Please fix this and reinstall this package." >&2 13 | exit 1 14 | fi 15 | if [ "`id -g helios`" -eq 0 ]; then 16 | echo "The helios user must not have root as primary group. 17 | Please fix this and reinstall this package." >&2 18 | exit 1 19 | fi 20 | if getent group docker >/dev/null 2>&1; then 21 | echo "* Adding helios user to docker group." >&2 22 | usermod -aG docker helios 23 | fi 24 | # ensure home directory ownership 25 | mkdir -p /var/lib/helios-agent 26 | su - helios -c "test -O /var/lib/helios-agent && 27 | test -G /var/lib/helios-agent" || \ 28 | chown -R helios:helios /var/lib/helios-agent 29 | fi 30 | 31 | # Start helios-agent 32 | if which initctl >/dev/null && initctl version | grep -q upstart; then 33 | # Using upstart 34 | initctl stop helios-agent >/dev/null 2>&1 || true 35 | initctl start helios-agent || true 36 | else 37 | # Using SysV init scripts 38 | /etc/init.d/helios-agent stop >/dev/null 2>&1 || true 39 | /etc/init.d/helios-agent start || true 40 | fi 41 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/coordination/CuratorClientFactory.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.coordination; 22 | 23 | import java.util.List; 24 | import org.apache.curator.RetryPolicy; 25 | import org.apache.curator.framework.AuthInfo; 26 | import org.apache.curator.framework.CuratorFramework; 27 | import org.apache.curator.framework.api.ACLProvider; 28 | 29 | public interface CuratorClientFactory { 30 | 31 | public CuratorFramework newClient(String connectString, 32 | int sessionTimeoutMs, 33 | int connectionTimeoutMs, 34 | RetryPolicy retryPolicy, 35 | ACLProvider aclProvider, 36 | List authorization); 37 | 38 | } 39 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/metrics/ReportingResourceMethodDispatchAdapter.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master.metrics; 22 | 23 | import com.spotify.helios.servicescommon.statistics.MasterMetrics; 24 | import com.sun.jersey.spi.container.ResourceMethodDispatchAdapter; 25 | import com.sun.jersey.spi.container.ResourceMethodDispatchProvider; 26 | 27 | public class ReportingResourceMethodDispatchAdapter implements ResourceMethodDispatchAdapter { 28 | 29 | private final MasterMetrics metrics; 30 | 31 | public ReportingResourceMethodDispatchAdapter(final MasterMetrics metrics) { 32 | this.metrics = metrics; 33 | } 34 | 35 | @Override 36 | public ResourceMethodDispatchProvider adapt(final ResourceMethodDispatchProvider provider) { 37 | return new ReportingResourceMethodDispatchProvider(provider, metrics); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/HeliosRuntimeException.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common; 22 | 23 | public class HeliosRuntimeException extends RuntimeException { 24 | 25 | public HeliosRuntimeException() { 26 | } 27 | 28 | public HeliosRuntimeException(final String message) { 29 | super(message); 30 | } 31 | 32 | public HeliosRuntimeException(final String message, final Throwable cause) { 33 | super(message, cause); 34 | } 35 | 36 | public HeliosRuntimeException(final Throwable cause) { 37 | super(cause); 38 | } 39 | 40 | public HeliosRuntimeException(final String message, final Throwable cause, 41 | final boolean enableSuppression, 42 | final boolean writableStackTrace) { 43 | super(message, cause, enableSuppression, writableStackTrace); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/metrics/HealthCheckGauge.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master.metrics; 22 | 23 | import com.codahale.metrics.Gauge; 24 | import com.codahale.metrics.health.HealthCheck; 25 | import com.codahale.metrics.health.HealthCheckRegistry; 26 | 27 | /** 28 | * This class reports the specified health check as a boolean gauge metric. 29 | */ 30 | public class HealthCheckGauge implements Gauge { 31 | 32 | private final HealthCheckRegistry registry; 33 | private final String name; 34 | 35 | public HealthCheckGauge(final HealthCheckRegistry registry, final String name) { 36 | this.registry = registry; 37 | this.name = name; 38 | } 39 | 40 | @Override 41 | public Integer getValue() { 42 | final HealthCheck.Result result = registry.runHealthCheck(name); 43 | return result.isHealthy() ? 1 : 0; 44 | } 45 | } 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/client/Endpoint.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.client; 22 | 23 | import java.net.InetAddress; 24 | import java.net.URI; 25 | 26 | /** 27 | * A Helios master endpoint which is represented by a {@link URI} and an IP address resolved from 28 | * the hostname in the URI. 29 | */ 30 | public interface Endpoint { 31 | 32 | /** 33 | * Returns the {@link URI} of the endpoint. 34 | * A valid URI for Helios must have a scheme that's either http or https, 35 | * a hostname, and a port. I.e. it must be of the form http(s)://heliosmaster.domain.net:port. 36 | * It's up to the implementation to enforce this. 37 | * 38 | * @return URI 39 | */ 40 | URI getUri(); 41 | 42 | /** 43 | * Returns the {@link InetAddress} to which the URI's hostname resolves. 44 | * 45 | * @return List of InetAddress 46 | */ 47 | InetAddress getIp(); 48 | 49 | } 50 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/rollingupdate/RollingUpdateOp.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.rollingupdate; 22 | 23 | import com.google.common.collect.ImmutableList; 24 | import com.spotify.helios.servicescommon.coordination.ZooKeeperOperation; 25 | import java.util.Map; 26 | 27 | public class RollingUpdateOp { 28 | 29 | private final ImmutableList operations; 30 | private final ImmutableList> events; 31 | 32 | public RollingUpdateOp(final ImmutableList operations, 33 | final ImmutableList> events) { 34 | this.operations = operations; 35 | this.events = events; 36 | } 37 | 38 | public ImmutableList operations() { 39 | return operations; 40 | } 41 | 42 | public ImmutableList> events() { 43 | return events; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /helios-tools/src/test/java/com/spotify/helios/cli/TestUtils.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Tools 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.cli; 22 | 23 | import com.google.common.collect.Lists; 24 | import java.util.List; 25 | 26 | /** 27 | * Common test utilities. 28 | */ 29 | public class TestUtils { 30 | 31 | /** 32 | * Get the first column from an output of a table whose entries are separated by newlines and 33 | * columns are separated by spaces. 34 | */ 35 | public static List readFirstColumnFromOutput(final String output, 36 | final boolean skipFirstRow) { 37 | final List values = Lists.newArrayList(); 38 | for (final String line : output.split("\n")) { 39 | final String col = line.split(" ")[0]; 40 | values.add(col); 41 | } 42 | if (skipFirstRow) { 43 | return values.subList(1, values.size()); 44 | } 45 | return values; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /helios-testing/src/main/java/com/spotify/helios/testing/LogStreamFollower.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.testing; 22 | 23 | import com.spotify.docker.client.LogMessage; 24 | import com.spotify.helios.common.descriptors.JobId; 25 | import java.io.IOException; 26 | import java.util.Iterator; 27 | 28 | /** 29 | * Follows a log stream in a blocking fashion. 30 | */ 31 | public interface LogStreamFollower { 32 | 33 | /** 34 | * Follows the specified log stream until it doesn't have any more log messages available. 35 | * 36 | * @param jobId the job id that the log stream belongs to 37 | * @param containerId the container id that the log stream belongs to 38 | * @param logStream the log stream to follow 39 | * 40 | * @throws IOException if an exception occurred 41 | */ 42 | void followLog(JobId jobId, String containerId, Iterator logStream) 43 | throws IOException; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /helios-tools/src/main/java/com/spotify/helios/cli/command/TargetAndClient.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Tools 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.cli.command; 22 | 23 | import com.google.common.base.Optional; 24 | import com.google.common.base.Preconditions; 25 | import com.spotify.helios.cli.Target; 26 | import com.spotify.helios.client.HeliosClient; 27 | 28 | public class TargetAndClient { 29 | private final Optional target; 30 | private final HeliosClient client; 31 | 32 | public TargetAndClient(final Target target, final HeliosClient client) { 33 | this.target = Optional.of(Preconditions.checkNotNull(target)); 34 | this.client = client; 35 | } 36 | 37 | public TargetAndClient(final HeliosClient client) { 38 | this.target = Optional.absent(); 39 | this.client = client; 40 | } 41 | 42 | public Optional getTarget() { 43 | return target; 44 | } 45 | 46 | public HeliosClient getClient() { 47 | return client; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/LoggingConfig.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common; 22 | 23 | import java.io.File; 24 | 25 | public class LoggingConfig { 26 | 27 | private final int verbosity; 28 | private final boolean syslog; 29 | private final File configFile; 30 | private final boolean noLogSetup; 31 | 32 | public LoggingConfig(final int verbosity, final boolean syslog, final File configFile, 33 | final boolean noLogSetup) { 34 | this.verbosity = verbosity; 35 | this.syslog = syslog; 36 | this.configFile = configFile; 37 | this.noLogSetup = noLogSetup; 38 | } 39 | 40 | public int getVerbosity() { 41 | return verbosity; 42 | } 43 | 44 | public boolean isSyslog() { 45 | return syslog; 46 | } 47 | 48 | public File getConfigFile() { 49 | return configFile; 50 | } 51 | 52 | public boolean getNoLogSetup() { 53 | return noLogSetup; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/ZooKeeperMetrics.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | import java.util.concurrent.TimeUnit; 24 | import org.apache.curator.framework.state.ConnectionState; 25 | 26 | /** 27 | * This interface lets us report ZooKeeper metrics. 28 | */ 29 | public interface ZooKeeperMetrics { 30 | 31 | /** 32 | * Call this to report a transient ZooKeeper error. 33 | */ 34 | void zookeeperTransientError(); 35 | 36 | /** 37 | * Call this to update the appropriate timer with an event duration. 38 | * 39 | * @param name Durations with the same name get recorded under the same timer. 40 | * @param duration Duration of the event. 41 | * @param timeUnit Time unit of the duration. 42 | */ 43 | void updateTimer(String name, long duration, TimeUnit timeUnit); 44 | 45 | void connectionStateChanged(ConnectionState newState); 46 | } 47 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/CommonConfiguration.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon; 22 | 23 | import io.dropwizard.Configuration; 24 | import java.util.List; 25 | 26 | public class CommonConfiguration> extends Configuration { 27 | 28 | private List kafkaBrokers; 29 | private List pubsubPrefixes; 30 | 31 | public List getKafkaBrokers() { 32 | return kafkaBrokers; 33 | } 34 | 35 | @SuppressWarnings("unchecked") 36 | public C setKafkaBrokers(List kafkaBrokers) { 37 | this.kafkaBrokers = kafkaBrokers; 38 | return (C) this; 39 | } 40 | 41 | public List getPubsubPrefixes() { 42 | return pubsubPrefixes; 43 | } 44 | 45 | @SuppressWarnings("unchecked") 46 | public C setPubsubPrefixes(List pubsubPrefixes) { 47 | this.pubsubPrefixes = pubsubPrefixes; 48 | return (C) this; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /bin/helios-agent: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | for i in "$@" 4 | do 5 | if [[ "$i" == "--help" || "$i" == "-h" ]] 6 | then 7 | as_service=false 8 | fi 9 | done 10 | 11 | if [ -z "$as_service" ] 12 | then 13 | : ${JMXPORT=9203} 14 | fi 15 | 16 | args=() 17 | dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 18 | 19 | if [[ -e "$dir/../helios-services" ]]; then 20 | jar="$(ls -t $dir/../helios-services/target/helios*-shaded.jar | grep -v sources | grep -v javadoc | head -n 1)" 21 | CLASSPATH="$(cd $(dirname $jar) && pwd -P)/$(basename $jar)" 22 | : ${JDWPPORT=5006} 23 | AGENTLIB=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$JDWPPORT 24 | echo "running in helios project, using $CLASSPATH" 1>&2 25 | else 26 | CLASSPATH="/usr/share/helios/lib/services/*" 27 | fi 28 | 29 | if [ $JMXPORT ]; then 30 | args=("${args[@]}" 31 | -Dcom.sun.management.jmxremote.port=$JMXPORT 32 | -Dcom.sun.management.jmxremote.rmi.port=$JMXPORT 33 | -Dcom.sun.management.jmxremote.ssl=false 34 | -Dcom.sun.management.jmxremote.authenticate=false ) 35 | fi 36 | 37 | # Allow the path to the java installation to be specified in the JAVA environment variable. 38 | # This can be useful if you want to run helios-agent using a different version of Java than the 39 | # default version on the host (possibly set up through update-alternatives) 40 | if [ -z $JAVA ]; then 41 | JAVA=java 42 | fi 43 | 44 | exec $JAVA \ 45 | $HELIOS_AGENT_JVM_OPTS \ 46 | "${args[@]}" \ 47 | -Djava.net.preferIPv4Stack=true \ 48 | -cp "$CLASSPATH" \ 49 | $AGENTLIB \ 50 | com.spotify.helios.agent.AgentMain \ 51 | "$@" 52 | -------------------------------------------------------------------------------- /bin/helios-master: -------------------------------------------------------------------------------- 1 | #!/bin/bash -e 2 | 3 | for i in "$@" 4 | do 5 | if [[ "$i" == "--help" || "$i" == "-h" ]] 6 | then 7 | as_service=false 8 | fi 9 | done 10 | 11 | if [ -z "$as_service" ] 12 | then 13 | : ${JMXPORT=9202} 14 | : ${JDWPPORT=5005} 15 | AGENTLIB=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=$JDWPPORT 16 | fi 17 | 18 | args=() 19 | dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 20 | 21 | if [[ -e "$dir/../helios-services" ]]; then 22 | jar="$(ls -t $dir/../helios-services/target/helios*-shaded.jar | grep -v sources | grep -v javadoc | head -n 1)" 23 | CLASSPATH="$(cd $(dirname $jar) && pwd -P)/$(basename $jar)" 24 | echo "running in helios project, using $CLASSPATH" 1>&2 25 | else 26 | CLASSPATH="/usr/share/helios/lib/services/*" 27 | fi 28 | 29 | if [ $JMXPORT ]; then 30 | args=("${args[@]}" 31 | -Dcom.sun.management.jmxremote.port=$JMXPORT 32 | -Dcom.sun.management.jmxremote.rmi.port=$JMXPORT 33 | -Dcom.sun.management.jmxremote.ssl=false 34 | -Dcom.sun.management.jmxremote.authenticate=false ) 35 | fi 36 | 37 | # Allow the path to the java installation to be specified in the JAVA environment variable. 38 | # This can be useful if you want to run helios-master using a different version of Java than the 39 | # default version on the host (possibly set up through update-alternatives) 40 | if [ -z $JAVA ]; then 41 | JAVA=java 42 | fi 43 | 44 | exec $JAVA \ 45 | $HELIOS_MASTER_JVM_OPTS \ 46 | "${args[@]}" \ 47 | -Djava.net.preferIPv4Stack=true \ 48 | -cp "$CLASSPATH" \ 49 | $AGENTLIB \ 50 | com.spotify.helios.master.MasterMain \ 51 | "$@" 52 | -------------------------------------------------------------------------------- /helios-system-tests/src/main/java/com/spotify/helios/system/MasterResolutionFailureMessageTest.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios System Tests 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.system; 22 | 23 | import static org.junit.Assert.assertTrue; 24 | 25 | import com.spotify.helios.cli.CliMain; 26 | import java.io.ByteArrayOutputStream; 27 | import java.io.PrintStream; 28 | import org.junit.Test; 29 | 30 | public class MasterResolutionFailureMessageTest { 31 | 32 | @Test 33 | public void test() throws Exception { 34 | final String[] commands = { "jobs", "--no-log-setup", "-d", "bogusdomain" }; 35 | final ByteArrayOutputStream stdout = new ByteArrayOutputStream(); 36 | final ByteArrayOutputStream stderr = new ByteArrayOutputStream(); 37 | new CliMain(new PrintStream(stdout), new PrintStream(stderr), commands).run(); 38 | final String string = stderr.toString(); 39 | assertTrue(string.trim().equals( 40 | "Failed to resolve helios master in bogusdomain (srv: helios)")); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /helios-client/src/test/java/com/spotify/helios/common/PeriodicResolverTest.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 - 2019 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common; 22 | 23 | import static org.hamcrest.MatcherAssert.assertThat; 24 | import static org.mockito.Mockito.mock; 25 | import static org.mockito.Mockito.when; 26 | 27 | import com.google.common.collect.ImmutableList; 28 | import java.net.URI; 29 | import java.util.concurrent.Executors; 30 | import org.hamcrest.Matchers; 31 | import org.junit.Test; 32 | 33 | public class PeriodicResolverTest { 34 | 35 | private final Resolver resolver = mock(Resolver.class); 36 | 37 | @Test 38 | public void testGet() { 39 | final URI uri = URI.create("https://foo.bar.com"); 40 | when(resolver.resolve("foo", "bar")).thenReturn(ImmutableList.of(uri)); 41 | final PeriodicResolver sut = PeriodicResolver.create("foo", "bar", resolver, 42 | Executors.newSingleThreadScheduledExecutor()); 43 | assertThat(sut.get(), Matchers.contains(uri)); 44 | } 45 | } -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/DockerVersionSupplier.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | import com.spotify.docker.client.DockerClient; 24 | import com.spotify.docker.client.exceptions.DockerException; 25 | import java.util.function.Supplier; 26 | 27 | /** 28 | * Returns the version from the DockerClient, formatted as a String so that exceptions can be 29 | * propogated by returning special String values. 30 | */ 31 | public class DockerVersionSupplier implements Supplier { 32 | 33 | private final DockerClient dockerClient; 34 | 35 | public DockerVersionSupplier(final DockerClient dockerClient) { 36 | this.dockerClient = dockerClient; 37 | } 38 | 39 | @Override 40 | public String get() { 41 | try { 42 | return dockerClient.version().version(); 43 | } catch (DockerException | InterruptedException e) { 44 | return "n/a"; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /helios-testing/src/test/java/com/spotify/helios/testing/CapturingAppender.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.testing; 22 | 23 | import ch.qos.logback.classic.spi.ILoggingEvent; 24 | import ch.qos.logback.core.AppenderBase; 25 | import com.google.common.collect.ImmutableList; 26 | 27 | final class CapturingAppender extends AppenderBase { 28 | 29 | private final ImmutableList.Builder eventsBuilder; 30 | 31 | private CapturingAppender(final ImmutableList.Builder eventsBuilder) { 32 | this.eventsBuilder = eventsBuilder; 33 | } 34 | 35 | public static CapturingAppender create() { 36 | return new CapturingAppender(ImmutableList.builder()); 37 | } 38 | 39 | @Override 40 | protected void append(final ILoggingEvent eventObject) { 41 | eventsBuilder.add(eventObject); 42 | } 43 | 44 | public ImmutableList events() { 45 | return eventsBuilder.build(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /helios-testing/src/main/java/com/spotify/helios/testing/HeliosDeployment.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.testing; 22 | 23 | import com.google.common.net.HostAndPort; 24 | import com.spotify.helios.client.HeliosClient; 25 | 26 | /** 27 | * A HeliosDeployment represents a collection of Helios masters and agents upon which jobs may be 28 | * run. 29 | */ 30 | public interface HeliosDeployment extends AutoCloseable { 31 | 32 | /** 33 | * A helios client connected to the master(s) of this helios deployment. 34 | * 35 | * @return {@link HeliosClient} 36 | */ 37 | HeliosClient client(); 38 | 39 | /** 40 | * Returns the host and port information that the deployment is available at. 41 | * 42 | * @return {@link HostAndPort} 43 | */ 44 | // TODO (mbrown): should this be URI to capture scheme info also? 45 | HostAndPort address(); 46 | 47 | /** 48 | * Undeploy (shut down) this Helios deployment. 49 | */ 50 | void close(); 51 | } 52 | 53 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/AgentModelTaskResource.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | import com.codahale.metrics.annotation.Timed; 24 | import com.spotify.helios.common.descriptors.JobId; 25 | import com.spotify.helios.common.descriptors.Task; 26 | import java.util.Map; 27 | import javax.ws.rs.GET; 28 | import javax.ws.rs.Path; 29 | import javax.ws.rs.Produces; 30 | import javax.ws.rs.core.MediaType; 31 | 32 | // Would be /tasks, but dropwizard uses /tasks/. 33 | 34 | /** 35 | * Makes it so you can view the tasks as the Agent sees things. 36 | */ 37 | @Path("/helios/tasks") 38 | @Produces(MediaType.APPLICATION_JSON) 39 | public class AgentModelTaskResource { 40 | private final ZooKeeperAgentModel model; 41 | 42 | public AgentModelTaskResource(final ZooKeeperAgentModel model) { 43 | this.model = model; 44 | } 45 | 46 | @GET 47 | @Timed 48 | public Map getTasks() { 49 | return model.getTasks(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/AgentModelTaskStatusResource.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | import com.codahale.metrics.annotation.Timed; 24 | import com.spotify.helios.common.descriptors.JobId; 25 | import com.spotify.helios.common.descriptors.TaskStatus; 26 | import java.util.Map; 27 | import javax.ws.rs.GET; 28 | import javax.ws.rs.Path; 29 | import javax.ws.rs.Produces; 30 | import javax.ws.rs.core.MediaType; 31 | 32 | /** 33 | * Makes it so you can view the status of tasks as the Agent sees things. 34 | */ 35 | @Path("/helios/taskstatus") 36 | @Produces(MediaType.APPLICATION_JSON) 37 | public class AgentModelTaskStatusResource { 38 | private final ZooKeeperAgentModel model; 39 | 40 | public AgentModelTaskStatusResource(final ZooKeeperAgentModel model) { 41 | this.model = model; 42 | } 43 | 44 | @GET 45 | @Timed 46 | public Map getTaskStatus() { 47 | return model.getTaskStatuses(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/resources/MastersResource.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master.resources; 22 | 23 | import static javax.ws.rs.core.MediaType.APPLICATION_JSON; 24 | 25 | import com.codahale.metrics.annotation.ExceptionMetered; 26 | import com.codahale.metrics.annotation.Timed; 27 | import com.spotify.helios.master.MasterModel; 28 | import java.util.List; 29 | import javax.ws.rs.GET; 30 | import javax.ws.rs.Path; 31 | import javax.ws.rs.Produces; 32 | 33 | @Path("/masters") 34 | public class MastersResource { 35 | 36 | private final MasterModel model; 37 | 38 | public MastersResource(final MasterModel model) { 39 | this.model = model; 40 | } 41 | 42 | /** 43 | * Returns a list of names of running Helios masters. 44 | * 45 | * @return The list of names. 46 | */ 47 | @GET 48 | @Produces(APPLICATION_JSON) 49 | @Timed 50 | @ExceptionMetered 51 | public List list() { 52 | return model.getRunningMasters(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/NoOpContainerDecorator.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | import com.google.common.base.Optional; 24 | import com.spotify.docker.client.messages.ContainerConfig; 25 | import com.spotify.docker.client.messages.HostConfig; 26 | import com.spotify.docker.client.messages.ImageInfo; 27 | import com.spotify.helios.common.descriptors.Job; 28 | 29 | /** 30 | * A {@link ContainerDecorator} that does, as its name would imply, nothing. 31 | */ 32 | public class NoOpContainerDecorator implements ContainerDecorator { 33 | 34 | @Override 35 | public void decorateHostConfig(Job job, Optional dockerVersion, 36 | HostConfig.Builder hostConfig) { 37 | //noop 38 | } 39 | 40 | @Override 41 | public void decorateContainerConfig(Job job, ImageInfo imageInfo, Optional dockerVersion, 42 | ContainerConfig.Builder containerConfig) { 43 | //noop 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /helios-client/src/test/java/com/spotify/helios/common/VersionCompatibilityTest.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common; 22 | 23 | import static com.spotify.helios.common.VersionCompatibility.Status; 24 | import static org.junit.Assert.assertEquals; 25 | 26 | import org.junit.Test; 27 | 28 | public class VersionCompatibilityTest { 29 | 30 | @Test 31 | public void test() { 32 | final PomVersion server = PomVersion.parse("1.3.9"); 33 | assertEquals(Status.EQUAL, VersionCompatibility.getStatus(server, server)); 34 | assertEquals(Status.COMPATIBLE, VersionCompatibility.getStatus( 35 | server, PomVersion.parse("1.3.10"))); 36 | assertEquals(Status.COMPATIBLE, VersionCompatibility.getStatus( 37 | server, PomVersion.parse("1.2.8"))); 38 | assertEquals(Status.MAYBE, VersionCompatibility.getStatus( 39 | server, PomVersion.parse("1.4.8"))); 40 | assertEquals(Status.INCOMPATIBLE, VersionCompatibility.getStatus( 41 | server, PomVersion.parse("9.0.0"))); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/agent/ContainerDecorator.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | import com.google.common.base.Optional; 24 | import com.spotify.docker.client.messages.ContainerConfig; 25 | import com.spotify.docker.client.messages.HostConfig; 26 | import com.spotify.docker.client.messages.ImageInfo; 27 | import com.spotify.helios.common.descriptors.Job; 28 | 29 | /** 30 | * An interface to allow you to change the {@link HostConfig} and {@link ContainerConfig} objects 31 | * before they are sent to Docker. This way you can set defaults, or intercept various things. 32 | * 33 | *

See: {@link SyslogRedirectingContainerDecorator} for an example. 34 | */ 35 | public interface ContainerDecorator { 36 | 37 | void decorateHostConfig(Job job, Optional dockerVersion, HostConfig.Builder hostConfig); 38 | 39 | void decorateContainerConfig(Job job, ImageInfo imageInfo, Optional dockerVersion, 40 | ContainerConfig.Builder containerConfig); 41 | } 42 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/FastForwardConfig.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon; 22 | 23 | import com.google.common.net.HostAndPort; 24 | import java.util.Optional; 25 | 26 | public class FastForwardConfig { 27 | 28 | private final Optional address; 29 | private final int intervalSeconds; 30 | private final String key; 31 | 32 | public FastForwardConfig(Optional address, int intervalSeconds, String key) { 33 | this.address = address.map(HostAndPort::fromString); 34 | this.intervalSeconds = intervalSeconds; 35 | this.key = key; 36 | } 37 | 38 | /** 39 | * Connection address, empty means use default. 40 | * 41 | * @return An {@link Optional} of {@link HostAndPort} 42 | */ 43 | public Optional getAddress() { 44 | return address; 45 | } 46 | 47 | public int getReportingIntervalSeconds() { 48 | return intervalSeconds; 49 | } 50 | 51 | public String getMetricKey() { 52 | return key; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/MeterRates.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | import com.codahale.metrics.Meter; 24 | 25 | public class MeterRates { 26 | private final double oneMinuteRate; 27 | private final double fiveMinuteRate; 28 | private final double fifteenMinuteRate; 29 | 30 | public MeterRates(Meter meter) { 31 | this(meter.getOneMinuteRate(), meter.getFiveMinuteRate(), meter.getFifteenMinuteRate()); 32 | } 33 | 34 | public MeterRates(double oneMinuteRate, double fiveMinuteRate, double fifteenMinuteRate) { 35 | this.oneMinuteRate = oneMinuteRate; 36 | this.fiveMinuteRate = fiveMinuteRate; 37 | this.fifteenMinuteRate = fifteenMinuteRate; 38 | } 39 | 40 | public double getOneMinuteRate() { 41 | return oneMinuteRate; 42 | } 43 | 44 | public double getFiveMinuteRate() { 45 | return fiveMinuteRate; 46 | } 47 | 48 | public double getFifteenMinuteRate() { 49 | return fifteenMinuteRate; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /helios-services/src/test/java/com/spotify/helios/agent/AgentParserTest.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.agent; 22 | 23 | import com.google.common.collect.ImmutableList; 24 | import java.util.List; 25 | import java.util.function.Predicate; 26 | import java.util.function.UnaryOperator; 27 | import org.junit.Rule; 28 | import org.junit.Test; 29 | import org.junit.rules.ExpectedException; 30 | 31 | public class AgentParserTest { 32 | 33 | @Rule 34 | public final ExpectedException exception = ExpectedException.none(); 35 | 36 | @Test 37 | @SuppressWarnings("ReturnValueIgnored") 38 | public void testValidateArgument() { 39 | final Predicate isOdd = num -> num % 2 == 1; 40 | 41 | final UnaryOperator> testFn = 42 | nums -> AgentParser.validateArgument(nums, isOdd, n -> n + " is expected to be odd"); 43 | 44 | testFn.apply(ImmutableList.of(1, 3, 5, 7)); 45 | 46 | exception.expect(IllegalArgumentException.class); 47 | testFn.apply(ImmutableList.of(1, 3, 5, 7, 8)); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/descriptors/Descriptor.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common.descriptors; 22 | 23 | import static java.nio.charset.StandardCharsets.UTF_8; 24 | 25 | import com.fasterxml.jackson.core.JsonProcessingException; 26 | import com.spotify.helios.common.Json; 27 | import java.io.IOException; 28 | 29 | public abstract class Descriptor { 30 | 31 | public String toJsonString() { 32 | return Json.asStringUnchecked(this); 33 | } 34 | 35 | public byte[] toJsonBytes() { 36 | try { 37 | return Json.asBytes(this); 38 | } catch (JsonProcessingException e) { 39 | throw new RuntimeException(e); 40 | } 41 | } 42 | 43 | public static T parse(final byte[] bytes, Class clazz) 44 | throws IOException { 45 | return Json.read(bytes, clazz); 46 | } 47 | 48 | public static T parse(final String value, Class clazz) 49 | throws IOException { 50 | return parse(value.getBytes(UTF_8), clazz); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /helios-testing/src/test/java/com/spotify/helios/testing/JobsTest.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Testing Library 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.testing; 22 | 23 | import static org.hamcrest.Matchers.both; 24 | import static org.hamcrest.Matchers.containsString; 25 | import static org.hamcrest.Matchers.startsWith; 26 | import static org.junit.Assert.assertThat; 27 | 28 | import com.spotify.helios.common.descriptors.Job; 29 | import org.junit.Test; 30 | 31 | public class JobsTest { 32 | 33 | @Test 34 | public void testGetJobDescription() { 35 | final String image = "spotify/busybox:latest"; 36 | 37 | final Job job = Job.newBuilder() 38 | .setImage(image) 39 | .setName("testGetJobDescription") 40 | .setVersion("1") 41 | .build(); 42 | final String shortHash = job.getId().getHash().substring(0, 7); 43 | 44 | // Simple test to verify the job description contains the image name and a shortened job hash. 45 | assertThat(Jobs.getJobDescription(job), 46 | both(startsWith(image)).and(containsString(shortHash))); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /helios-service-registration/src/main/java/com/spotify/helios/serviceregistration/ServiceRegistrar.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Service Registration 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.serviceregistration; 22 | 23 | /** 24 | * A registrar for service endpoints. 25 | */ 26 | public interface ServiceRegistrar extends AutoCloseable { 27 | 28 | /** 29 | * Asynchronously register a set of service endpoints with a registry. Does not block. 30 | * 31 | * @param registration The service endpoints. 32 | * 33 | * @return A handle that can be used to unregister using 34 | * {@link #unregister(ServiceRegistrationHandle)}. 35 | */ 36 | ServiceRegistrationHandle register(ServiceRegistration registration); 37 | 38 | /** 39 | * Unregister a set of service endpoints previously registered. 40 | * 41 | * @param handle A handle returned by {@link #register(ServiceRegistration)}. 42 | */ 43 | void unregister(ServiceRegistrationHandle handle); 44 | 45 | /** 46 | * Close this registrar, possibly unregistering all registered service endpoints. 47 | */ 48 | void close(); 49 | } 50 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/protocol/HostRegisterResponse.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common.protocol; 22 | 23 | import com.fasterxml.jackson.annotation.JsonProperty; 24 | import com.spotify.helios.common.Json; 25 | 26 | public class HostRegisterResponse { 27 | 28 | public enum Status { 29 | OK, INVALID_ID 30 | } 31 | 32 | private final Status status; 33 | private final String host; 34 | 35 | public HostRegisterResponse(@JsonProperty("status") Status status, 36 | @JsonProperty("host") String host) { 37 | this.status = status; 38 | this.host = host; 39 | } 40 | 41 | public Status getStatus() { 42 | return status; 43 | } 44 | 45 | public String getHost() { 46 | return host; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "HostRegisterResponse{" 52 | + "status=" + status 53 | + ", host='" + host + '\'' 54 | + '}'; 55 | } 56 | 57 | public String toJsonString() { 58 | return Json.asStringUnchecked(this); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /pubkey.asc: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP PUBLIC KEY BLOCK----- 2 | Version: GnuPG v1 3 | 4 | mQENBFPjrqABCADi0lyTMCHywYJo3geGxrPXIpSsGKEZ2IaPJ/15x2+7Afe5uYHw 5 | zod6ydmwN31drrxV9i4vXf3hLU45YT8z3rkSvD7psvZTNcoNvNdg1hjuh8uUGyJy 6 | fxDWR0Obg5yO85w215J1lOYPX/6ZCOXdOlwPszdnkqechXZ6QHm23wf018YYnDgF 7 | DdIJkrBPVIN+kqKEWM+aiA5BHhncQ4HSOMLidLRZ1NvwZdJqr/P90o5LP4NhKkiA 8 | xL9vRoXhLb7fIcnFGUBEtzD4OWpySXgTsiQd2kE269vUNIWEeo1iAtVT14T/m+ii 9 | 76MxCqkU1U/02G8xHJG+dr9akGvWykbt8xeRABEBAAG0FlNwb3RpZnkgSGVsaW9z 10 | IFByb2plY3SJAT4EEwECACgFAlPjrqACGwMFCQHhM4AGCwkIBwMCBhUIAgkKCwQW 11 | AgMBAh4BAheAAAoJEPsKzrqIh/R3DTkH/A+ZiCuJj5UGFwz9I+2LYLiNShRKgRzJ 12 | LigKiOxA3mQjvnBxh6Zvqo04oN9s9qIozysioGdXodXbiqhEL+Mka2QK3PAJ0lmo 13 | n+/SQZEATfkwKg6XXOGITMlgWdvNuETav1Uv75G0dP4LyUSGHLSOxH5CCeapDsN+ 14 | EZ3nLTGG5TtIdGs0gjBA6KFYTtpxj8IdGOS5iGxbyho7rRQ9yw/e3EMV3Y3SRY1q 15 | R9Zb9i3pPcczEsHR791ltBESpN5z/iCkDdCZXlxUSAxfbnLuzd12G3xGj+TeuHsd 16 | 5SaZ1Z68s+QEHD8g04geuZxI2jLMFsbBmDT/0iVGxxuGKKOqyJpu77K5AQ0EU+Ou 17 | oAEIAPJgu46kt0g0k4IFdxY6LRrY8+oAw7kSVKmfk+bo9D8EBiKfhuRyBjj4mUGx 18 | Me5k/KpKJOS7mL4uX54PDalGhTC5QmyTrmc4iu3ULkY1nz8oNbIBptPDP2Mai4P3 19 | UkmhWQNF+Lx/RsJM24t3dtJi6JnKmR3Em2pUTxYJoZrF8jQdL0Iw6OcKEzaZw8nw 20 | NvXKAg9fHy8uuFOaGatgYq3Qj6h5F+O5dvU9UiYtWCfMVEtor2gmZK/1tppR8k0W 21 | P+fwaE2M/Vl3pzuQUwwDjM54h0/QXsHiSqd5SHjf/BMdQ4rRLG3A6cLzjo4rYwoK 22 | 24CLEpt4pzCVJPugzxXfFdqXViEAEQEAAYkBJQQYAQIADwUCU+OuoAIbDAUJAeEz 23 | gAAKCRD7Cs66iIf0d1npB/9e5n7o9lcBCtadTa5NkXht4HxeE0PxerKxAdB+vgFO 24 | cQ/vPc3PCs7qssfIKOGqyb2PB74zfb5zgRolPFPTr5R6sRWIUZAo8jb2P5oDC3cU 25 | pUvRjfvgKXfbUzJyuGpNiFkLAphHwu3zjO4wJ2h7yxRs5Wxb4CcMJwjWbDrZuoRp 26 | ihAd7b6T+mkYGfOtUW1KCRZYUZVdGuFN9pZiy7Qq4ptV+434HT0UEZ2zzGn+kOTf 27 | upgrP6NNYy5okTThDxZ951z5Aybp/M561PZfrAZqZtbcPHWctd+0pRe3BrubVCEa 28 | g4vsASHR8o0YAuoJeMB+wwruj/UUJFG8ESI0viRi8hUd 29 | =fJa4 30 | -----END PGP PUBLIC KEY BLOCK----- 31 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | 4 | ## Response Times 5 | 6 | This project is developed and maintained by an infrastructure team at Spotify. Lots of teams at 7 | Spotify use the latest version of Helios in production for mission-critical systems. 8 | 9 | That being said, this is our day job where our primary users are our colleagues. 10 | So we might be slow in getting back to you because we're busy working on Spotify-specific things 11 | or because your issues are being prioritized behind those of our colleagues. 12 | 13 | Please poke us if you feel you're being neglected, and we'll do our best to get back to you. 14 | 15 | ## Related Tools You May Find Useful 16 | 17 | If you like this project, you might also like [docker-maven-plugin][2], [docker-client][3], [docker-gc][4], 18 | [helios-skydns][5], and [helios-consul][6]. 19 | 20 | 21 | ## Reporting Bugs 22 | 23 | Please make sure you're using the latest version of Helios for master, agent, and CLI. Helios is 24 | released continuously as it's developed so new releases come out almost as frequently as we 25 | commit to master. 26 | 27 | ## Contributing 28 | 29 | Before creating a new issue, see if there's already an existing issue. 30 | 31 | If you create a minor bugfix, feel free to submit a PR. 32 | If your PR is for a significant change or a new feature, feel free to ask for our feedback 33 | before writing code to check we're on the same page. 34 | 35 | Here are [instructions on building and testing the project][1]. 36 | 37 | [1]: https://github.com/spotify/helios#build--test 38 | [2]: https://github.com/spotify/docker-maven-plugin 39 | [3]: https://github.com/spotify/docker-client 40 | [4]: https://github.com/spotify/docker-gc 41 | [5]: https://github.com/spotify/helios-skydns 42 | [6]: https://github.com/spotify/helios-consul 43 | 44 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/VersionCheckResponse.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common; 22 | 23 | import com.fasterxml.jackson.annotation.JsonProperty; 24 | import com.spotify.helios.common.VersionCompatibility.Status; 25 | 26 | public class VersionCheckResponse { 27 | private final PomVersion serverVersion; 28 | private final Status status; 29 | private final String recommendedVersion; 30 | 31 | public VersionCheckResponse(@JsonProperty("status") VersionCompatibility.Status status, 32 | @JsonProperty("version") PomVersion serverVersion, 33 | @JsonProperty("recommendedVersion") String recommendedVersion) { 34 | this.status = status; 35 | this.serverVersion = serverVersion; 36 | this.recommendedVersion = recommendedVersion; 37 | } 38 | 39 | public PomVersion getServerVersion() { 40 | return serverVersion; 41 | } 42 | 43 | public Status getStatus() { 44 | return status; 45 | } 46 | 47 | public String getRecommendedVersion() { 48 | return recommendedVersion; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /helios-client/src/test/resources/UIDCACert.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCeFABwDBUnApJR 3 | Geo/+64E11KZ3rpoF+VJIX9apBq3DmF5GxhYb5PiFTkOPLN34PwLf3qLez93SSgZ 4 | v/lXeQhWnudJlYLTwyHleDYo6uzFzG97ud10DKLEL4qz6tsNmgOFN7DUsARWcniQ 5 | eA+PlB7FOAq+Np3AU3thtysN9pj/7kfthiHSpnaolauqdQFug2QC/TsuqlpbwdZm 6 | C+0jcjz6F7FPOSo/dkTb1gy04sjoA6QRuCAskjlkQvSuviU48CYZwlXJg87mR6t5 7 | yDk1kv1NSUcL0g7PNC/yIMZiNKzkP+hVOYc/EK8dJv2u8rmp74xCW7Zq6lhejgZF 8 | 27pmsTuLAgMBAAECggEAWGidWg0X42pnxJ32yfQLfj+ivdW4cTE0FfN7E4mGO2z6 9 | jM3fjs5QafguoczHHrugmxmfwtSaSS+MEuKwJADX7gIPHrNUqPSQR5M0zyucYn+U 10 | tiDcPuQ2P/zK2Rb3jiLd5yqfZkRPGL4Kudm78jQIBYrzTzCih4bpEVxs4vFQ3olX 11 | eqNArqgIzUiB81m3CLFfrIsxHXnN8/1Gs6z1iHxwZ1gIP5HO4lgQ3pgBnxtLwpVS 12 | TeT3niS655KYyX19kBIZz+QDTzD9OevyR0yHXxSKkXNQ5ruAosJfkcNlD9tNJMM3 13 | XX/DihyV+xUWCfFjab8baZ4V9tHyu8lOUzoNidTC6QKBgQDMip+sjJqL1rn1TruZ 14 | zYdvC1RHL4EWOhddushgacAlrDwsK0Vz70S7G3mG2TAb14p+p2VrTWdSYm+9t/Mc 15 | aI/RCLKWl4PRDFC+GiiMZqMe/SfMi0/5Cb3oBGdIWwj2t4Nuw4MRR6sBUvBjpHGw 16 | s4a8fASM45LD15CbTsdxszbz9wKBgQDF2O6NAd+jyv9UzQchudT5asVqwVJaPReV 17 | iv3Av8zc82f8k6rcibXnxWXmxfL0YEpmc+dfk8SxJ7ZIYCayll20+9gUYgQKJtAd 18 | CJQG/nIU2PFDOhhqR/Ada6PVtzXm4jeIUoC47xPuu724s9MLKWReUJRj/St/ZPDK 19 | ClUoLOnoDQKBgFPshPt9bWP3JLG8Lkk7BVjQozHaEfMWvsOcgd7dRROwCbhtwL+C 20 | 6waCjWiA8LZbx92TvY87YStybDrBoSSE2o2ALhaP8Gvzy6VUglKpQkDSymOovZWH 21 | I75xIBeWEqV4QptN6RdL+qQ+bZfUvzkrUBtCH3PXZD6q0hCHUFocmG2dAoGAI4ao 22 | jzle5xJ0ds26EhxEWeUKPfkoyHtf2MJ0fj/ykVpDud7qN1+jAlM30RCKZ8dClNML 23 | IOZv0z/GQ4jAaiEGApGWY1KWVxxREmWP7xGRepzZ9bBg4fS48Q97A806KJNGVXw7 24 | EPodIikkEB56Lu7nzue5PZsgTGfbtOvWDrjB56ECgYAqJfM8huco+Zq2b22RWXCS 25 | 2pD5JHWEOqoBGDi6l23CvLksDM376PIaQKPha7l8nhX86Me7qWP9psKt0ij03MsC 26 | upFOfYFNhtaWVwtGzrzBxd/Y2ZTT4UrNBqSSsUj8eEcZfdQ9uWeP2WorQnKiAaPs 27 | 1m1xH4RSEml75Kj5Kx3HxQ== 28 | -----END PRIVATE KEY----- -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/statistics/MetricsContextImpl.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.statistics; 22 | 23 | import com.codahale.metrics.Timer.Context; 24 | 25 | /** 26 | * Creation of this class marks the beginning of a call to some service. Either {@link #success()} 27 | * {@link #userError()} or {@link #failure()} should be called when the call completes to record the 28 | * duration of the call and increment the call counter. 29 | */ 30 | public class MetricsContextImpl implements MetricsContext { 31 | 32 | private final RequestMetrics metrics; 33 | private final Context timerContext; 34 | 35 | public MetricsContextImpl(RequestMetrics metrics) { 36 | this.metrics = metrics; 37 | this.timerContext = metrics.begin(); 38 | } 39 | 40 | @Override 41 | public void success() { 42 | metrics.success(timerContext); 43 | } 44 | 45 | @Override 46 | public void failure() { 47 | metrics.failure(timerContext); 48 | } 49 | 50 | @Override 51 | public void userError() { 52 | metrics.userError(timerContext); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/protocol/HostDeregisterResponse.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common.protocol; 22 | 23 | import com.fasterxml.jackson.annotation.JsonProperty; 24 | import com.spotify.helios.common.Json; 25 | 26 | public class HostDeregisterResponse { 27 | 28 | public enum Status { 29 | OK, NOT_FOUND, JOBS_STILL_DEPLOYED 30 | } 31 | 32 | private final Status status; 33 | private final String host; 34 | 35 | public HostDeregisterResponse(@JsonProperty("status") Status status, 36 | @JsonProperty("host") String host) { 37 | this.status = status; 38 | this.host = host; 39 | } 40 | 41 | public Status getStatus() { 42 | return status; 43 | } 44 | 45 | public String getHost() { 46 | return host; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return "HostDeregisterResponse{" 52 | + "status=" + status 53 | + ", host='" + host + '\'' 54 | + '}'; 55 | } 56 | 57 | public String toJsonString() { 58 | return Json.asStringUnchecked(this); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /.circleci/Dockerfile: -------------------------------------------------------------------------------- 1 | # This image is used to run the tests for helios on CircleCI 2 | # It's published as spotify/helios-test-container:1. 3 | 4 | # Get docker CLI binary only 5 | FROM ubuntu:bionic as docker-cli-getter 6 | WORKDIR /tmp 7 | RUN apt-get -qq update && apt-get -qq install \ 8 | wget 9 | RUN wget --quiet https://download.docker.com/linux/static/stable/x86_64/docker-18.06.1-ce.tgz && \ 10 | tar xzvf docker-18.06.1-ce.tgz 11 | 12 | 13 | # Dockerfile for the container CircleCI uses to build and test helios 14 | FROM ubuntu:bionic 15 | 16 | RUN apt-get -qq update && apt-get -qq install \ 17 | # Required tools for primary containers that aren't already in bionic 18 | # https://circleci.com/docs/2.0/custom-images/#required-tools-for-primary-containers 19 | git ssh \ 20 | # tools we need 21 | wget maven lsof jq python-minimal python-pip 22 | 23 | # Download and validate checksum of openjdk-11 24 | # Checksum from https://download.java.net/java/ga/jdk11/openjdk-11_linux-x64_bin.tar.gz.sha256 25 | RUN wget --quiet https://download.java.net/java/ga/jdk11/openjdk-11_linux-x64_bin.tar.gz && \ 26 | echo '3784cfc4670f0d4c5482604c7c513beb1a92b005f569df9bf100e8bef6610f2e openjdk-11_linux-x64_bin.tar.gz' > openjdk-11-sha256sum.txt && \ 27 | sha256sum -c openjdk-11-sha256sum.txt 28 | 29 | # Install openjdk-11 30 | RUN tar -xzf openjdk-11_linux-x64_bin.tar.gz && \ 31 | mkdir -p /usr/lib/jvm && \ 32 | mv jdk-11 /usr/lib/jvm/openjdk-11 && \ 33 | update-alternatives --install /usr/bin/java java /usr/lib/jvm/openjdk-11/bin/java 20000 && \ 34 | update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/openjdk-11/bin/javac 20000 35 | 36 | # Add docker CLI 37 | COPY --from=docker-cli-getter /tmp/docker/docker /usr/bin/docker 38 | 39 | # Install codecov 40 | RUN pip install codecov 41 | 42 | ENV JAVA_HOME /usr/lib/jvm/openjdk-11 43 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/protocol/VersionResponse.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common.protocol; 22 | 23 | import com.fasterxml.jackson.annotation.JsonProperty; 24 | import com.spotify.helios.common.Json; 25 | 26 | public class VersionResponse { 27 | 28 | private final String clientVersion; 29 | private final String masterVersion; 30 | 31 | public VersionResponse(@JsonProperty("clientVersion") String clientVersion, 32 | @JsonProperty("masterVersion") String masterVersion) { 33 | this.clientVersion = clientVersion; 34 | this.masterVersion = masterVersion; 35 | } 36 | 37 | public String getClientVersion() { 38 | return clientVersion; 39 | } 40 | 41 | public String getMasterVersion() { 42 | return masterVersion; 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "VersionResponse{" 48 | + "clientVersion='" + clientVersion + '\'' 49 | + ", masterVersion='" + masterVersion + '\'' 50 | + '}'; 51 | } 52 | 53 | public String toJsonString() { 54 | return Json.asStringUnchecked(this); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/coordination/PathFactory.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.coordination; 22 | 23 | import org.apache.zookeeper.common.PathUtils; 24 | 25 | public class PathFactory { 26 | 27 | private final String base; 28 | 29 | public PathFactory(final String base, final String... parts) { 30 | final String joined = join(base, parts); 31 | this.base = joined.startsWith("/") ? joined : "/" + joined; 32 | PathUtils.validatePath(base); 33 | } 34 | 35 | public String path(final String... parts) { 36 | final String path = join(base, parts); 37 | PathUtils.validatePath(path); 38 | return path; 39 | } 40 | 41 | private String join(final String base, final String... parts) { 42 | final StringBuilder builder = new StringBuilder(base); 43 | for (final String part : parts) { 44 | if (part.isEmpty()) { 45 | continue; 46 | } 47 | if (builder.charAt(builder.length() - 1) != '/' && part.charAt(0) != '/') { 48 | builder.append('/'); 49 | } 50 | builder.append(part); 51 | } 52 | return builder.toString(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/master/metrics/ReportingResourceMethodDispatchProvider.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.master.metrics; 22 | 23 | import com.spotify.helios.servicescommon.statistics.MasterMetrics; 24 | import com.sun.jersey.api.model.AbstractResourceMethod; 25 | import com.sun.jersey.spi.container.ResourceMethodDispatchProvider; 26 | import com.sun.jersey.spi.dispatch.RequestDispatcher; 27 | 28 | public class ReportingResourceMethodDispatchProvider implements ResourceMethodDispatchProvider { 29 | 30 | private final ResourceMethodDispatchProvider provider; 31 | private final MasterMetrics metrics; 32 | 33 | public ReportingResourceMethodDispatchProvider(final ResourceMethodDispatchProvider provider, 34 | final MasterMetrics metrics) { 35 | this.provider = provider; 36 | this.metrics = metrics; 37 | } 38 | 39 | @Override 40 | public RequestDispatcher create(final AbstractResourceMethod abstractResourceMethod) { 41 | final RequestDispatcher dispatcher = provider.create(abstractResourceMethod); 42 | return new ReportingResourceMethodDispatcher(dispatcher, metrics); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/InterruptingExecutionThreadService.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon; 22 | 23 | import com.google.common.util.concurrent.AbstractExecutionThreadService; 24 | import com.google.common.util.concurrent.ThreadFactoryBuilder; 25 | import java.util.concurrent.Executor; 26 | import java.util.concurrent.ExecutorService; 27 | import java.util.concurrent.Executors; 28 | 29 | public abstract class InterruptingExecutionThreadService extends AbstractExecutionThreadService { 30 | 31 | private final ExecutorService executorService; 32 | private final String name; 33 | 34 | protected InterruptingExecutionThreadService(final String name) { 35 | this.name = name; 36 | this.executorService = Executors.newSingleThreadExecutor( 37 | new ThreadFactoryBuilder().setNameFormat(name + "-%d").build()); 38 | } 39 | 40 | @Override 41 | protected String serviceName() { 42 | return name; 43 | } 44 | 45 | @Override 46 | protected Executor executor() { 47 | return executorService; 48 | } 49 | 50 | @Override 51 | protected void triggerShutdown() { 52 | executorService.shutdownNow(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /helios-services/src/main/java/com/spotify/helios/servicescommon/coordination/Check.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Services 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.servicescommon.coordination; 22 | 23 | import org.apache.curator.framework.api.transaction.CuratorTransaction; 24 | 25 | public class Check implements ZooKeeperOperation { 26 | 27 | private final String path; 28 | 29 | public Check(final String path) { 30 | this.path = path; 31 | } 32 | 33 | @Override 34 | public void register(final CuratorTransaction transaction) throws Exception { 35 | transaction.check().forPath(path); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "Check{" 41 | + "path='" + path + '\'' 42 | + '}'; 43 | } 44 | 45 | @Override 46 | public boolean equals(final Object obj) { 47 | if (this == obj) { 48 | return true; 49 | } 50 | if (obj == null || getClass() != obj.getClass()) { 51 | return false; 52 | } 53 | 54 | final Check check = (Check) obj; 55 | 56 | return path != null ? path.equals(check.path) : check.path == null; 57 | 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | return path != null ? path.hashCode() : 0; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /helios-client/src/main/java/com/spotify/helios/common/protocol/TaskStatusEvents.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios Client 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.common.protocol; 22 | 23 | import com.fasterxml.jackson.annotation.JsonProperty; 24 | import com.spotify.helios.common.Json; 25 | import com.spotify.helios.common.descriptors.TaskStatusEvent; 26 | import java.util.List; 27 | 28 | public class TaskStatusEvents { 29 | 30 | public enum Status { 31 | OK, JOB_ID_NOT_FOUND 32 | } 33 | 34 | private final List events; 35 | private final Status status; 36 | 37 | public TaskStatusEvents(@JsonProperty("events") List events, 38 | @JsonProperty("status") Status status) { 39 | this.events = events; 40 | this.status = status; 41 | } 42 | 43 | public Status getStatus() { 44 | return status; 45 | } 46 | 47 | public List getEvents() { 48 | return events; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "TaskStatusEvents{" 54 | + "events=" + events 55 | + ", status=" + status 56 | + '}'; 57 | } 58 | 59 | public String toJsonString() { 60 | return Json.asStringUnchecked(this); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /helios-system-tests/src/main/java/com/spotify/helios/system/ZooKeeperBadNodeTest.java: -------------------------------------------------------------------------------- 1 | /*- 2 | * -\-\- 3 | * Helios System Tests 4 | * -- 5 | * Copyright (C) 2016 Spotify AB 6 | * -- 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * -/-/- 19 | */ 20 | 21 | package com.spotify.helios.system; 22 | 23 | import com.spotify.helios.ZooKeeperTestManager; 24 | import com.spotify.helios.ZooKeeperTestingClusterManager; 25 | import com.spotify.helios.client.HeliosClient; 26 | import org.junit.Test; 27 | 28 | public class ZooKeeperBadNodeTest extends SystemTestBase { 29 | 30 | /** 31 | * This is a testing cluster that has one peer that can't be resolved. Note that this is different 32 | * from a cluster where a peer is down (that's tested in {@link ZooKeeperHeliosFailoverTest}). 33 | */ 34 | private final ZooKeeperTestManager zkc = new ZooKeeperTestingClusterManager() { 35 | @Override 36 | public String connectString() { 37 | return super.connectString() + ",node-that-doesnt-exist:1738"; 38 | } 39 | }; 40 | 41 | @Test 42 | public void testGetJobsWithBadNode() throws Exception { 43 | startDefaultMaster("--zk-cluster-id=" + zkClusterId); 44 | 45 | final HeliosClient client = defaultClient(); 46 | client.jobs().get(); 47 | } 48 | 49 | @Override 50 | protected ZooKeeperTestManager zooKeeperTestManager() { 51 | return zkc; 52 | } 53 | 54 | } 55 | --------------------------------------------------------------------------------