diff --git a/command/agent/agent.go b/command/agent/agent.go index 69a1093c9c..cc6b8e93a1 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -17,6 +17,7 @@ import ( "github.com/hashicorp/consul/command/flags" "github.com/hashicorp/consul/lib" "github.com/hashicorp/consul/logger" + "github.com/hashicorp/consul/service_os" "github.com/hashicorp/go-checkpoint" multierror "github.com/hashicorp/go-multierror" "github.com/hashicorp/logutils" @@ -277,6 +278,8 @@ func (c *cmd) run(args []string) int { case ch := <-agent.ReloadCh(): sig = syscall.SIGHUP reloadErrCh = ch + case <-service_os.Shutdown_Channel(): + sig = os.Interrupt case <-c.shutdownCh: sig = os.Interrupt case err := <-agent.RetryJoinCh(): diff --git a/main.go b/main.go index 855967af47..9755775f2c 100644 --- a/main.go +++ b/main.go @@ -8,6 +8,7 @@ import ( "github.com/hashicorp/consul/command" "github.com/hashicorp/consul/lib" + _ "github.com/hashicorp/consul/service_os" "github.com/mitchellh/cli" ) diff --git a/service_os/service.go b/service_os/service.go new file mode 100644 index 0000000000..432baaf2ad --- /dev/null +++ b/service_os/service.go @@ -0,0 +1,7 @@ +package service_os + +var chanGraceExit = make(chan int) + +func Shutdown_Channel() <-chan int { + return chanGraceExit +} diff --git a/service_os/service_windows.go b/service_os/service_windows.go new file mode 100644 index 0000000000..d7fc245f52 --- /dev/null +++ b/service_os/service_windows.go @@ -0,0 +1,42 @@ +//+build windows + +package service_os + +import ( + wsvc "golang.org/x/sys/windows/svc" +) + +type serviceWindows struct{} + +func init() { + interactive, err := wsvc.IsAnInteractiveSession() + if err != nil { + panic(err) + } + if interactive { + return + } + go func() { + _ = wsvc.Run("", serviceWindows{}) + }() +} + +func (serviceWindows) Execute(args []string, r <-chan wsvc.ChangeRequest, s chan<- wsvc.Status) (svcSpecificEC bool, exitCode uint32) { + const accCommands = wsvc.AcceptStop | wsvc.AcceptShutdown + s <- wsvc.Status{State: wsvc.StartPending} + + s <- wsvc.Status{State: wsvc.Running, Accepts: accCommands} + for { + c := <-r + switch c.Cmd { + case wsvc.Interrogate: + s <- c.CurrentStatus + case wsvc.Stop, wsvc.Shutdown: + chanGraceExit <- 1 + s <- wsvc.Status{State: wsvc.StopPending} + return false, 0 + } + } + + return false, 0 +} diff --git a/website/source/docs/guides/index.html.md b/website/source/docs/guides/index.html.md index 096aa58066..946a96c7ea 100644 --- a/website/source/docs/guides/index.html.md +++ b/website/source/docs/guides/index.html.md @@ -45,3 +45,5 @@ The following guides are available: * [Sentinel](/docs/guides/sentinel.html) - This guide covers using Sentinel for policy enforcement in Consul. * [Server Performance](/docs/guides/performance.html) - This guide covers minimum requirements for Consul servers as well as guidelines for running Consul servers in production. + +* [Windows Service](/docs/guides/windows-guide.html) - This guide covers how to run Consul as a service on Windows. \ No newline at end of file diff --git a/website/source/docs/guides/windows-guide.html.md b/website/source/docs/guides/windows-guide.html.md new file mode 100644 index 0000000000..43d75347d8 --- /dev/null +++ b/website/source/docs/guides/windows-guide.html.md @@ -0,0 +1,71 @@ +--- +layout: "docs" +page_title: "Windows Service" +sidebar_current: "docs-guides-windows-service" +description: |- + By using the _sc_ command either on Powershell or + the Windows command line, you can make Consul run as a service. For more details about the _sc_ command + the Windows page for [sc](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682107(v=vs.85).aspx) + should help you get started. + +--- + +# Overview +By using the _sc_ command either on Powershell or +the Windows command line, you can make Consul run as a service. For more details about the _sc_ command +the Windows page for [sc](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682107(v=vs.85).aspx) +should help you get started. + +Please remember to create a permanent directory for storing the configuration files. It is always +advisable to start Consul with the _-config-dir_ option. + +The steps presented here , we assume that the user has launched Powershell with _Adminstrator_ capabilities. + +## Running Consul run as a service on Windows + +### Installing Consul as a Service + +Download the Consul binary for your architecture. + + Use the _sc_ command to create a Service named **Consul**, which starts in the _dev_ mode. + + ```text + sc.exe create "Consul" binPath="Path to the Consul.exe arg1 arg2 ...argN" + [SC] CreateService SUCCESS + ``` + + + If you get an output that is similar to the one above, then your service is + registered with the Service manager. + + + If you get an error, please check that + you have specified the proper path to the binary and check if you've entered the arguments correctly for the Consul + service. + + +### Running Consul as a service + +You have two ways to start the service. + +* Go to the Windows Service Manager, and look for **Consul** under the + service name. Click the _start_ button to start the service. +* Using the _sc_ command: + + ```text + sc.exe start "Consul" + + SERVICE_NAME: Consul + TYPE : 10 WIN32_OWN_PROCESS + STATE : 4 RUNNING + (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN) + WIN32_EXIT_CODE : 0 (0x0) + SERVICE_EXIT_CODE : 0 (0x0) + CHECKPOINT : 0x0 + WAIT_HINT : 0x0 + PID : 8008 + FLAGS : + ``` + +The service automatically starts up during/after boot, so you don't need to +launch Consul from the command-line again. \ No newline at end of file diff --git a/website/source/layouts/docs.erb b/website/source/layouts/docs.erb index c42ddccf0b..635a11e9d7 100644 --- a/website/source/layouts/docs.erb +++ b/website/source/layouts/docs.erb @@ -359,6 +359,9 @@ Certificates > Server Performance + > + Windows (Service) +