ScoopInstaller / Scoop

A command-line installer for Windows.
https://scoop.sh
Other
21.12k stars 1.41k forks source link

scoop services install <app> #1526

Open r15ch13 opened 7 years ago

r15ch13 commented 7 years ago

Discussion about implementing service management similar to brew services.

Previous discussions about this topic: #1512, #513

I stumbled over Laravel Valet for Windows which uses WinSW to setup a PHP developing environment. I know this is not the purpose of scoop, but I would like to create a documentation for setting up an updateable PHP dev environment. These zero-configuration setups (like xampp or valet) are cool, but most of them don't allow changing components or updates at all. With scoop it would be easy to swap out nginx for caddy/apache, MySQL for MariaDB and so on. Loosely coupled!

We could utilize https://github.com/kohsuke/winsw for installing/starting/stopping services. In each manifest, we could provide a basic configuration that is copied to ~/scoop/persist/<app>/service.xml so it can be easily modified.

E.g. scoop services install nginx would copy winsw.exe to ~/scoop/services/nginx.exe (winsw has to be renamed) and register it, using a configuration located in ~/scoop/persist/nginx/service.xml. All other commands run|start|stop|restart can be implemented like brew services commands.

Example installation for a full PHP environment:

λ scoop install php
λ scoop install composer
λ scoop install nginx
λ scoop install mariadb
λ scoop services install php-fpm
λ scoop services start php-fpm
λ scoop services install nginx
λ scoop services start nginx

Programs which could be run as a service:

What to you guys think?

lukesampson commented 7 years ago

WinSW sounds like it would be useful for programs that don't know how to run as a Windows service. Is that necessary though?

If it only needs to work with programs that do know how to run a service, the sc.exe commands are pretty straightforward, and they don't need the extra steps of copying the WinSW exe and writing XML.

Scoop command sc.exe equivalent
scoop service install unbound sudo sc.exe create Unbound binPath= "'$env:userprofile\scoop\apps\unbound\current\unbound.exe' -c '$env:userprofile\scoop\apps\unbound\current\service.conf' -w service" start= auto DisplayName= "Unbound DNS Validator"
scoop service start unbound sudo sc.exe start Unbound
scoop service stop unbound sudo sc.exe stop Unbound
scoop service restart unbound sudo sc.exe stop Unbound; sudo sc.exe start Unbound
r15ch13 commented 7 years ago

None of the programs I listed above can be registered as proper Windows services. They have to be started with WinSW or NSSM.

lukesampson commented 7 years ago

Did I screw something up in the Unbound example above? It seemed to work for me, and their offical Windows installer installs it as a service.

I would have thought any program suitable for use in a production environment on Windows would have support for running as a service.

And for running in development, would it be nicer to start a background process (as @nueko mentioned in #1513) so you didn't have to run as admin?

r15ch13 commented 7 years ago

Okay unbound has build Windows services support. But registering PHP with sc.exe results in a service hanging in starting state.

deevus commented 7 years ago

What about after a reboot?

On Wed, May 31, 2017 at 10:53 AM Richard Kuhnt notifications@github.com wrote:

Okay unbound has build Windows services support. But registering PHP with sc.exe results in a service hanging in starting state.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/lukesampson/scoop/issues/1526#issuecomment-305050503, or mute the thread https://github.com/notifications/unsubscribe-auth/AA0Qgu5OAqiSWjQVInR4u8QRInMijPIgks5r_Ln-gaJpZM4NqSMo .

r15ch13 commented 7 years ago

Nope, PHP and the others don't support the Windows Service API. It can't be stopped or restarted properly.

See: https://stackoverflow.com/questions/10061191/add-nginx-exe-as-windows-system-service-like-apache/12964345#12964345

tresf commented 7 years ago

Perhaps use https://pecl.php.net/package/win32service.

r15ch13 commented 7 years ago

That could be a solution for PHP yes. Leaves us with the rest :smile:

lukesampson commented 7 years ago

Roger that. You've convinced me that WinSW is the way to go.

nueko commented 7 years ago

Won't sc.exe hurt non-admin user?

r15ch13 commented 7 years ago

WinSW won't work either if you don't have admin privileges.

nueko commented 7 years ago

just my thought service start <app> command can be run with Start-Process with hidden window

nueko commented 7 years ago

Just quick experiment usage: scoop process start mariadb/mysqld.exe

~\scoop\current\libexec\scoop-process.ps1

param($cmd, $app, $argls)
. "$psscriptroot\..\lib\core.ps1"

# get Requested process
$requestedProcess = Get-Process $app -ErrorAction SilentlyContinue
$app, $process = $app.split('/')

function stop_process () {
    if ($requestedProcess) {
        Write-Host "Trying to gracefully exit..." -F Green

        # try gracefully first
        $requestedProcess.CloseMainWindow() | Out-Null

        # kill after five seconds
        Start-Sleep 5

        if (!$requestedProcess.HasExited) {
            Write-Host "Forcing stop process..." -F Yellow
            $requestedProcess | Stop-Process -Force
            $requestedProcess.Close();
        }
        else {
            Write-Host "Process $app sucessfully stoped" -F Green
        }
    }
}

function start_process () {
    if($argls) {
        Start-Process -WorkingDirectory $(appdir($app)) -FilePath ($process, $app)[!$process] -A $argls -WindowStyle Hidden -PassThru
    } else {
        Start-Process -WorkingDirectory $(appdir($app)) -FilePath ($process, $app)[!$process] -WindowStyle Hidden -PassThru
    }
}
switch ($cmd) {
    "stop" { stop_process }
    "start" { start_process }
    default { "scoop process: cmd '$cmd' not supported"; my_usage; exit 1 }
}
gpetrov commented 3 years ago

@r15ch13 and @lukesampson - what happen to this great services implementation? It looks amazing and it brings scoop to the level of Homebrew on mac, where you can also manage services directly.

So please finalize it.

jtagcat commented 3 years ago

I'd add syncthing to the list (easy to implement, and popular enough).

What I'd like to see is scoop service enable/disable, enabling start on system startup.

yarcowong commented 2 years ago

So, what is this feature for now? I think the feature of start/stop server is enough for now. (without restarting the service when windows boot again). At least, we use windows for development purchase, must be rare to use it as a real server with services under *nix~ And for now, it is a pain to start nginx which is installed by scoop~ I need to start it by hand and close whole powershell window if I want to restart it after change the config (not quite sure, there will be other solution)

Em... nginx -s reload works though.

bharatvaj commented 2 years ago

Hi, I tried srvany-ng recently and it looks promising for implementing this feature as it is very simple and easily scriptable. WinSW looks like it does way too much IMO, like providing start/stop/status commands and xml configuration for passing args. I liked the idea of @nueko running it as a executable at first but that would mean net start and net stop commands cannot be used and scoop has to maintain a separate list of running services.

I hacked to together a install-service.ps1 and uninstall-service.ps1 for mpd with sc, srvany-ng and powershell's registry interface which should be very portable and allows the native net start/stop to work which scoop can provide a wrapper for if needed.

install-service.ps1

$SERVICE_NAME='mpd'
$SERVICE_ARGS='C:\Users\UserName\.config\mpd\mpd.conf'
$SrvAnyNgBinPath=$(Get-Command -Name srvany-ng -ErrorAction Ignore).Source
$exists=$?
if (-Not $exists ) {
    echo "ERROR: srvany-ng does not exist in path"
    exit
}
$ServiceBinPath=$(Get-Command -Name $SERVICE_NAME -ErrorAction Ignore).Source
$exists=$?
if (-Not $exists ) {
    echo "ERROR: $SERVICE_NAME does not name a service"
    return -1
}
sc.exe create $SERVICE_NAME start= auto binPath= "$SrvAnyNgBinPath"
$NotError=$?
if (-Not $NotError) { 
    # echo "ERROR: Unable to create service"
    # exit /b
    echo "$SERVICE_NAME already exists, old entry will be deleted, are you sure? [Y/n]: Y"
    sc.exe config $SERVICE_NAME start= auto binPath= "$SrvAnyNgBinPath"
}

# TODO if ServiceBinPath is null exit this, possibly rollback

Set-ItemProperty -Path Registry::HKLM\SYSTEM\CurrentControlSet\Services\$SERVICE_NAME\Parameters -Name Application -Value "$ServiceBinPath"
# TODO Use proper AppDir
Set-ItemProperty -Path Registry::HKLM\SYSTEM\CurrentControlSet\Services\$SERVICE_NAME\Parameters -Name AppDirectory -Value "$Env:Scoop\shims"
Set-ItemProperty -Path Registry::HKLM\SYSTEM\CurrentControlSet\Services\$SERVICE_NAME\Parameters -Name AppParameters -Value "$SERVICE_ARGS

uninstall-service.ps1

$SERVICE_NAME="mpd"
Remove-Item -Path Registry::HKLM\SYSTEM\CurrentControlSet\Services\$SERVICE_NAME -Force

The above scripts basically installs and uninstalls mpd and should be very easy to make it generic and to integrate with scoop install/uninstall given the manifest has something like,

{
  "version": "0.22",
  "...": "...",
  "serivice": {
    "name": "mpd",
    "args": "",
    "workdingDirectory": "$bin"
  }
}

And finally for the end user, it will be just typing the commands

net start mpd
net stop mpd
scoop service config mpd "C:\Users\Administrator\.config\mpd\mpd.confg"  # user should be able to pass custom args for the daemon program.

Programs which provide service implementation with their executables should work with net program like before.

gpetrov commented 1 year ago

Any new developments in the services support @lukesampson ?

r15ch13 commented 1 year ago

Unfortunately, since I opened this issue there has not been any progress or other attempts to implement it.

(Luke is not active on this project)