Enable fdroid deployment
This commit is contained in:
parent
cb149a93e1
commit
a3873e4dcd
|
@ -117,7 +117,6 @@ in {
|
|||
./roles/on-my-machine.nix
|
||||
./roles/headless.nix
|
||||
./roles/weechat
|
||||
./roles/kassandra-server.nix
|
||||
./roles/headless-mpd.nix
|
||||
./roles/mail.nix
|
||||
./roles/mail2rss.nix
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
{ pkgs, ... }: {
|
||||
systemd.user.services.kassandra = {
|
||||
Unit = { Description = "Kassandra Server"; };
|
||||
Service = {
|
||||
WorkingDirectory = "/var/www/kassandra";
|
||||
ExecStart = "/var/www/kassandra/backend -b '::1' ";
|
||||
Restart = "always";
|
||||
Environment = "PATH=${pkgs.coreutils}/bin/:${pkgs.taskwarrior}/bin";
|
||||
};
|
||||
Install = { WantedBy = [ "default.target" ]; };
|
||||
};
|
||||
}
|
|
@ -19,6 +19,7 @@ in {
|
|||
../../roles/coturn.nix
|
||||
../../roles/go-neb.nix
|
||||
../../roles/laminar
|
||||
../../roles/kassandra-server.nix
|
||||
./web.nix
|
||||
./mail.nix
|
||||
./boot.nix
|
||||
|
@ -38,7 +39,9 @@ in {
|
|||
'';
|
||||
startAgent = true;
|
||||
};
|
||||
java.enable = true;
|
||||
};
|
||||
nixpkgs.config.android_sdk.accept_license = true;
|
||||
systemd.services."pg_backup" = {
|
||||
script = let name = "matrix-synapse";
|
||||
in ''
|
||||
|
|
14
nixos/roles/kassandra-server.nix
Normal file
14
nixos/roles/kassandra-server.nix
Normal file
|
@ -0,0 +1,14 @@
|
|||
{ pkgs, ... }: {
|
||||
systemd.services.kassandra = {
|
||||
enable = true;
|
||||
description = "Kassandra Server";
|
||||
serviceConfig = let serverPath = "/var/cache/gc-links/kassandra-server";
|
||||
in {
|
||||
WorkingDirectory = serverPath;
|
||||
ExecStart = "${serverPath}/backend -b '::1' ";
|
||||
Restart = "always";
|
||||
Environment = "PATH=${pkgs.coreutils}/bin/:${pkgs.taskwarrior}/bin";
|
||||
User = "maralorn";
|
||||
};
|
||||
};
|
||||
}
|
|
@ -2,14 +2,26 @@
|
|||
let
|
||||
path = [ pkgs.git pkgs.nix pkgs.gnutar pkgs.gzip pkgs.openssh pkgs.laminar ];
|
||||
setup = ''
|
||||
set -e
|
||||
export PATH=${lib.makeBinPath path}:$PATH
|
||||
'';
|
||||
repo = "/var/www/fdroid";
|
||||
appName = "de.maralorn.kassandra";
|
||||
deploy = "${pkgs.writeShellScript "deploy" ''
|
||||
systemctl restart kassandra
|
||||
VERSIONCODE="1"
|
||||
rm ${repo}/repo/${appName}_$VERSIONCODE.apk
|
||||
cp /var/cache/gc-links/kassandra-android/android-app-release-unsigned.apk ${repo}/unsigned/${appName}_$VERSIONCODE.apk
|
||||
cd ${repo}
|
||||
export PATH=/run/current-system/sw/bin:$PATH
|
||||
export ANDROID_HOME=${pkgs.androidsdk_9_0}/libexec/android-sdk
|
||||
fdroid publish
|
||||
fdroid update
|
||||
''}";
|
||||
target = name: ''
|
||||
set -e
|
||||
${setup}
|
||||
export HOME=$PWD
|
||||
git clone git@localhost:kassandra2 kassandra
|
||||
cd kassandra
|
||||
git clone git@localhost:kassandra2 .
|
||||
git show -q
|
||||
echo "Evaluating nix-expression."
|
||||
export FLAGS='--builders @/etc/nix/machines --max-jobs 1'
|
||||
|
@ -19,11 +31,19 @@ let
|
|||
laminarc set "RESULTDRV=$drv"
|
||||
'';
|
||||
in {
|
||||
security.sudo.extraRules = [{
|
||||
commands = [{
|
||||
command = deploy;
|
||||
options = [ "NOPASSWD" ];
|
||||
}];
|
||||
users = [ "laminar" ];
|
||||
}];
|
||||
services.laminar.cfgFiles.jobs = {
|
||||
"kassandra.run" = pkgs.writeShellScript "kassandra" ''
|
||||
${setup}
|
||||
echo Launching and waiting for jobs lib, app, android and server
|
||||
laminarc run kassandra-lib kassandra-android kassandra-app kassandra-server
|
||||
/run/wrappers/bin/sudo ${deploy}
|
||||
'';
|
||||
"kassandra-lib.run" = pkgs.writeShellScript "kassandra-lib" (target "lib");
|
||||
"kassandra-app.run" = pkgs.writeShellScript "kassandra-app" (target "app");
|
||||
|
|
|
@ -15,7 +15,9 @@ import Control.Concurrent.Async ( forConcurrently_
|
|||
, race_
|
||||
, withAsync
|
||||
)
|
||||
import Control.Concurrent.STM ( check )
|
||||
import Control.Concurrent.STM ( check
|
||||
, retry
|
||||
)
|
||||
import Control.Exception ( bracket
|
||||
, catch
|
||||
, handle
|
||||
|
@ -23,6 +25,7 @@ import Control.Exception ( bracket
|
|||
, throwIO
|
||||
)
|
||||
import Data.Bits ( Bits((.|.)) )
|
||||
import qualified Data.Map as Map
|
||||
import qualified Data.Sequence as Seq
|
||||
import Data.String.Interpolate ( i )
|
||||
import Data.Text ( isInfixOf
|
||||
|
@ -33,7 +36,6 @@ import qualified Data.Text as T
|
|||
import Data.Time ( diffUTCTime
|
||||
, getCurrentTime
|
||||
)
|
||||
import qualified Data.Map as Map
|
||||
import Relude
|
||||
import Say ( say
|
||||
, sayErr
|
||||
|
@ -62,6 +64,7 @@ import System.IO ( BufferMode(LineBuffering)
|
|||
, hSetBuffering
|
||||
)
|
||||
import System.IO.Error
|
||||
import System.IO.Unsafe
|
||||
import System.Posix.Files ( groupReadMode
|
||||
, otherReadMode
|
||||
, ownerReadMode
|
||||
|
@ -74,15 +77,12 @@ import System.Posix.IO ( OpenFileFlags(exclusive)
|
|||
, fdWrite
|
||||
, openFd
|
||||
)
|
||||
import System.IO.Unsafe
|
||||
|
||||
|
||||
load Absolute ["laminarc", "nix-store"]
|
||||
|
||||
data JobResult = Success | Failure deriving (Show, Read, Eq, Ord, Enum)
|
||||
|
||||
data ReportLevel = None | Self | Children deriving (Show, Eq, Ord, Enum)
|
||||
|
||||
newtype JobException = JobException Text deriving (Show, Exception)
|
||||
throw = throwIO . JobException
|
||||
newtype WaitException = WaitException Text deriving (Show, Exception)
|
||||
|
@ -99,11 +99,6 @@ instance ExecArg Text where
|
|||
asArg = asArg . toString
|
||||
asArgFromList = asArgFromList . fmap toString
|
||||
|
||||
whenSelf level = when (level >= Self)
|
||||
whenChildren level = when (level >= Children)
|
||||
levelPrec Children = Self
|
||||
levelPrec _ = None
|
||||
|
||||
drvBasename derivationName =
|
||||
fromMaybe derivationName . viaNonEmpty last $ splitOn "/" derivationName
|
||||
|
||||
|
@ -115,9 +110,12 @@ runningPath, resultPath :: Text -> String
|
|||
runningPath p = [i|#{runningDir}/#{drvBasename p}|]
|
||||
resultPath p = [i|#{resultDir}/#{drvBasename p}|]
|
||||
|
||||
{-# NOINLINE depMap #-}
|
||||
depMap :: TVar (Map Text (Seq Text))
|
||||
depMap = unsafePerformIO $ newTVarIO mempty
|
||||
{-# NOINLINE jobMap #-}
|
||||
|
||||
data BuildState = Pending | Running | Complete deriving (Show, Eq)
|
||||
-- True means job is finished
|
||||
jobMap :: TVar (Map Text (TVar BuildState))
|
||||
jobMap = unsafePerformIO $ newTVarIO mempty
|
||||
|
||||
-- Bool means derivation itself needs to be build
|
||||
getDependenciesFromNix :: Text -> IO (Seq Text)
|
||||
|
@ -134,11 +132,8 @@ needsBuild derivationName = do
|
|||
|
||||
nixStoreRealiseDryRun :: Text -> IO (Seq Text)
|
||||
nixStoreRealiseDryRun derivationName = do
|
||||
maybeDeps <- Map.lookup derivationName <$> readTVarIO depMap
|
||||
deps <- maybe (process
|
||||
<$> (nix_store "-r" derivationName "--dry-run" &!> StdOut |> captureTrim)) pure maybeDeps
|
||||
whenNothing_ maybeDeps $ atomically $ modifyTVar' depMap (Map.insert derivationName deps)
|
||||
pure deps
|
||||
process
|
||||
<$> (nix_store "-r" derivationName "--dry-run" &!> StdOut |> captureTrim)
|
||||
where
|
||||
process =
|
||||
fromList
|
||||
|
@ -163,7 +158,6 @@ job derivationName = do
|
|||
createDirectoryIfMissing True resultDir
|
||||
writeFileText (resultPath derivationName) (show result)
|
||||
removeFile (runningPath derivationName)
|
||||
ensureDeps Children derivationName
|
||||
unlessM (needsBuild derivationName) $ do
|
||||
setResult Success
|
||||
say [i|Build for #{derivationName} had already happened.|]
|
||||
|
@ -182,13 +176,11 @@ job derivationName = do
|
|||
nixStoreRealise :: Text -> [Text] -> IO ()
|
||||
nixStoreRealise name flags = nix_store (["-r", name] <> flags)
|
||||
|
||||
ensureDeps :: ReportLevel -> Text -> IO ()
|
||||
ensureDeps level derivationName = do
|
||||
ensureDeps :: Text -> IO ()
|
||||
ensureDeps derivationName = do
|
||||
dependencies <- getDependenciesFromNix derivationName
|
||||
whenChildren level $ forM_ dependencies $ \dep -> say [i|Requiring #{dep}.|]
|
||||
forConcurrently_ dependencies (realise $ levelPrec level)
|
||||
`catch` \(JobException e) ->
|
||||
throw [i|#{e}\nFailed dependency for #{derivationName}|]
|
||||
forConcurrently_ dependencies realise `catch` \(JobException e) ->
|
||||
throw [i|#{e}\nFailed dependency for #{derivationName}|]
|
||||
|
||||
-- Nothing means failing to acquire lock on the derivation name for starting the job.
|
||||
tryQueue :: Text -> IO (Maybe Text)
|
||||
|
@ -223,14 +215,25 @@ tryQueue derivationName = handleExisting $ do
|
|||
defaultMode =
|
||||
ownerReadMode .|. ownerWriteMode .|. groupReadMode .|. otherReadMode
|
||||
|
||||
queueJobWithLaminarc :: ReportLevel -> Text -> IO Text
|
||||
queueJobWithLaminarc level derivationName =
|
||||
whenNothingM (tryQueue derivationName) (ensureRunningJob level derivationName)
|
||||
queueJobWithLaminarc :: Text -> IO Text
|
||||
queueJobWithLaminarc derivationName = whenNothingM
|
||||
(do
|
||||
jobMay <- tryQueue derivationName
|
||||
whenJust jobMay $ \jobName ->
|
||||
say [i|Job #{jobName} started for #{derivationName}. Waiting ...|]
|
||||
pure jobMay
|
||||
)
|
||||
(ensureRunningJob derivationName)
|
||||
|
||||
ensureRunningJob :: ReportLevel -> Text -> IO Text
|
||||
ensureRunningJob level derivationName = whenNothingM
|
||||
(getRunningJob derivationName)
|
||||
(queueJobWithLaminarc level derivationName)
|
||||
ensureRunningJob :: Text -> IO Text
|
||||
ensureRunningJob derivationName = whenNothingM
|
||||
(do
|
||||
jobMay <- getRunningJob derivationName
|
||||
whenJust jobMay $ \jobName ->
|
||||
say [i|Job #{jobName} running for #{derivationName}. Waiting ...|]
|
||||
pure jobMay
|
||||
)
|
||||
(queueJobWithLaminarc derivationName)
|
||||
|
||||
-- Nothing means there is no running Job.
|
||||
getRunningJob :: Text -> IO (Maybe Text)
|
||||
|
@ -244,52 +247,84 @@ getRunningJob derivationName = poll 0
|
|||
mayJob <- request
|
||||
if count < 50 && mayJob == Just ""
|
||||
then threadDelay 10000 >> poll (count + 1)
|
||||
else pure mayJob
|
||||
else do
|
||||
|
||||
realise :: ReportLevel -> Text -> IO ()
|
||||
realise level derivationName = do
|
||||
ensureDeps level derivationName
|
||||
needBuild <- needsBuild derivationName
|
||||
if needBuild
|
||||
then runBuild
|
||||
else whenSelf level $ say [i|#{derivationName} was already built.|]
|
||||
pure mayJob
|
||||
|
||||
getJobVar :: Text -> IO (TVar BuildState)
|
||||
getJobVar derivationName =
|
||||
atomically
|
||||
$ readTVar jobMap
|
||||
>>= maybe makeVar pure
|
||||
. Map.lookup derivationName
|
||||
where
|
||||
makeVar = do
|
||||
newVar <- newTVar Pending
|
||||
modifyTVar' jobMap (Map.insert derivationName newVar)
|
||||
pure newVar
|
||||
|
||||
realise :: Text -> IO ()
|
||||
realise derivationName = do
|
||||
jobVar <- getJobVar derivationName
|
||||
runHere <- atomically $ do
|
||||
jobState <- readTVar jobVar
|
||||
case jobState of
|
||||
Complete -> pure False
|
||||
Running -> retry
|
||||
Pending -> do
|
||||
writeTVar jobVar Running
|
||||
pure True
|
||||
when runHere $ do
|
||||
say [i|Requiring #{derivationName}...|]
|
||||
ensureDeps derivationName
|
||||
needBuild <- needsBuild derivationName
|
||||
if needBuild
|
||||
then runBuild
|
||||
else say [i|#{derivationName} was already built.|]
|
||||
atomically $ writeTVar jobVar Complete
|
||||
where
|
||||
runBuild = do
|
||||
jobName <- ensureRunningJob level derivationName
|
||||
whenSelf level
|
||||
$ say [i|Job #{jobName} running for #{derivationName}. Waiting ...|]
|
||||
jobName <- ensureRunningJob derivationName
|
||||
handleWaitFail $ waitForJob derivationName >>= \case
|
||||
Success ->
|
||||
whenSelf level $ say [i|Job #{jobName} completed #{derivationName}.|]
|
||||
Success -> say [i|Job #{jobName} completed #{derivationName}.|]
|
||||
Failure -> throw [i|Job #{jobName} failed #{derivationName}.|]
|
||||
processWaitFail (WaitException e) = do
|
||||
whenSelf level
|
||||
$ sayErr
|
||||
[i|Retrying to find or create a job for #{derivationName} after waiting for job failed with error "#{e}" |]
|
||||
realise level derivationName
|
||||
sayErr
|
||||
[i|Retrying to find or create a job for #{derivationName} after waiting for job failed with error "#{e}" |]
|
||||
realise derivationName
|
||||
handleWaitFail = handle processWaitFail
|
||||
|
||||
checkStaleness :: Text -> IO ()
|
||||
checkStaleness derivationName = forever $ do
|
||||
whenJustM (getRunningJob derivationName) $ \jobName ->
|
||||
handleJust (guard . isDoesNotExistError) (const pass) $ do
|
||||
nothingQueued <-
|
||||
T.null . decodeUtf8 <$> (laminarc "show-queued" |> captureTrim)
|
||||
checkStaleness :: IO ()
|
||||
checkStaleness = forever $ do
|
||||
handleJust (guard . isDoesNotExistError) (const pass) $ do
|
||||
nothingQueued <-
|
||||
T.null . decodeUtf8 <$> (laminarc "show-queued" |> captureTrim)
|
||||
when nothingQueued $ do
|
||||
knownJobs <-
|
||||
fmap strip
|
||||
. lines
|
||||
. decodeUtf8
|
||||
<$> (laminarc "show-running" |> captureTrim)
|
||||
now <- getCurrentTime
|
||||
fileTime <- getModificationTime (runningPath derivationName)
|
||||
let notRunning = not $ any (`isInfixOf` jobName) knownJobs
|
||||
oldEnough = diffUTCTime now fileTime > 60
|
||||
stale = notRunning && nothingQueued && oldEnough
|
||||
when stale $ do
|
||||
removeFile (runningPath derivationName)
|
||||
throwWait
|
||||
[i|File #{runningPath derivationName} claiming job name "#{jobName}" seems to be stale. Deleting File.|]
|
||||
threadDelay 10000000
|
||||
jobs <- Map.toList <$> readTVarIO jobMap
|
||||
forConcurrently_ jobs $ \(derivationName, jobVar) ->
|
||||
checkStalenessFor knownJobs jobVar derivationName
|
||||
threadDelay 60000000
|
||||
|
||||
checkStalenessFor :: [Text] -> TVar BuildState -> Text -> IO ()
|
||||
checkStalenessFor jobs jobVar derivationName =
|
||||
whenM ((== Running) <$> readTVarIO jobVar)
|
||||
$ whenJustM (getRunningJob derivationName)
|
||||
$ \jobName -> do
|
||||
say [i|Still waiting for job #{jobName} for #{derivationName}|]
|
||||
now <- getCurrentTime
|
||||
fileTime <- getModificationTime (runningPath derivationName)
|
||||
let notRunning = not $ any (`isInfixOf` jobName) jobs
|
||||
oldEnough = diffUTCTime now fileTime > 60
|
||||
stale = notRunning && oldEnough
|
||||
when stale $ do
|
||||
removeFile (runningPath derivationName)
|
||||
sayErr
|
||||
[i|File #{runningPath derivationName} claiming job name "#{jobName}" seems to be stale. Deleting File.|]
|
||||
|
||||
waitForJob :: Text -> IO JobResult
|
||||
waitForJob derivationName = do
|
||||
|
@ -297,11 +332,8 @@ waitForJob derivationName = do
|
|||
let finished = atomically (writeTVar done True)
|
||||
withManager $ \manager -> do
|
||||
_ <- watchDir manager runningDir fileDeleted (const finished)
|
||||
withAsync
|
||||
(whenNothingM_ (getRunningJob derivationName) finished)
|
||||
(const $ race_ (atomically $ readTVar done >>= check)
|
||||
(checkStaleness derivationName)
|
||||
)
|
||||
withAsync (whenNothingM_ (getRunningJob derivationName) finished)
|
||||
(const $ atomically $ readTVar done >>= check)
|
||||
resultText <-
|
||||
handleJust
|
||||
(guard . isDoesNotExistError)
|
||||
|
@ -329,6 +361,7 @@ main = do
|
|||
args <- fmap toText <$> getArgs
|
||||
case args of
|
||||
["realise-here", derivationName] -> job derivationName
|
||||
["realise" , derivationName] -> realise Children derivationName
|
||||
["realise", derivationName] ->
|
||||
race_ (realise derivationName) checkStaleness
|
||||
_ ->
|
||||
sayErr "Usage: realise-here <derivationName> | realise <derivationName>"
|
||||
|
|
|
@ -36,10 +36,9 @@ let
|
|||
checkout = ''
|
||||
git clone git@hera.m-0.eu:nixos-config . --config advice.detachedHead=false
|
||||
git checkout origin/$BRANCH
|
||||
git show -q
|
||||
REPODIR=.
|
||||
'';
|
||||
update-config =
|
||||
"${pkgs.systemd}/bin/systemctl start --no-block update-config";
|
||||
systems = [ "apollo" "hera" ];
|
||||
homes = lib.attrNames (import ../../../home-manager/machines.nix);
|
||||
mkHomeJob = (host: {
|
||||
|
@ -69,7 +68,7 @@ let
|
|||
'';
|
||||
});
|
||||
deployCommand = "${pkgs.writeShellScript "deploy-system-config"
|
||||
"${pkgs.systemd}/bin/systemctl start update-config"}";
|
||||
"${pkgs.systemd}/bin/systemctl start --no-block update-config"}";
|
||||
in {
|
||||
services.laminar.cfgFiles.jobs = {
|
||||
"test-config.run" = pkgs.writeHaskell "test-config" {
|
||||
|
|
|
@ -9,7 +9,6 @@ let
|
|||
(heading "ci.maralorn.de" "https://ci.maralorn.de")
|
||||
(job "kassandra")
|
||||
(job "test-config")
|
||||
(job "bump-and-test-config")
|
||||
(heading "haskell-taskwarrior"
|
||||
"https://hackage.haskell.org/package/taskwarrior")
|
||||
(badge "https://img.shields.io/hackage/v/taskwarrior.svg"
|
||||
|
|
|
@ -9,9 +9,9 @@ self: super: {
|
|||
extra-system-pkgs = {
|
||||
inherit (self.python3Packages) qrcode;
|
||||
inherit (self)
|
||||
git-crypt htop tree pwgen borgbackup inotifyTools direnv socat nmap ncdu
|
||||
htop tree pwgen borgbackup inotifyTools direnv socat nmap ncdu
|
||||
tcpdump tmux tig exa fzf ag fd bat ripgrep ranger pass sshuttle vnstat
|
||||
entr libargon2 mblaze niv compsize mediainfo asciinema gomuks nix-output-monitor fdroidserver adoptopenjdk-jre-bin;
|
||||
entr libargon2 mblaze niv compsize mediainfo asciinema gomuks nix-output-monitor fdroidserver;
|
||||
};
|
||||
|
||||
my-home-pkgs = {
|
||||
|
|
Loading…
Reference in a new issue