| Age | Commit message (Collapse) | Author |
|
Given the following command
#put!+0644 src/file dst/
If the dst is a directory, it would cause the directory permission
changes to 0644.
This changes fix it by checking if the destination is a directory first.
If we cannot stat the dst, skip the chmod/chown command.
|
|
When we made the refactoring, we forgot to run the test-integration task
which cause some tests are fails.
|
|
In the ExecResponse, store the event in the Output instead of message
data, so the server can iterate the Output directly and pass it to
WriteEvent directly.
The event ID now start at 1 with type "begin".
This is to minimize confusion when comparing empty Last-Event-ID from
client, which is equal to 0.
|
|
Using dummy date make the test output hard to read in verbose option,
because the program logs mixed with the test logs.
|
|
This is to fix flaky test on TestAwwanLocal.
|
|
In the test for AwwanLocal, use buffer with lock, so each write and
read is safe.
In the httpServer, the test found data race during ExecuteTail when
accessing [ExecResponse.EndAt].
We fix it by locking the resource during call to end() and when
accessing the EndAt field.
|
|
The "$noparse" option allow copying file without reading and parsing
the input file.
|
|
The latest mkosi use importctl instead of machinectl to import the
image.
There is an issue in mkosi.conf where build with Format=tar always get
compressed using zstd, but importctl unable to import it, so we need
to set CompressOutput=false.
The home directory mode needs to be set to open 0755, because now its
default to 0700, which makes the test failed to read file on others
user's home.
The pacman mirror changes to public one that is always available,
geo.mirror.pkgbuild.com.
The BUG_REPORT_URL in os-release for Arch changes which we need to
modify because its included in the test-container.
|
|
Previously, the "env-set" take the file argument as the last argument
and optional.
This changes move the file argument to the first argument so the bash
completion can detect and print the completion for list of keys.
While at it, fix handling key with quoted in EnvSet and EnvGet.
Closes: https://todo.sr.ht/~shulhan/awwan/10
|
|
The HTTP API for stopping execution have the following signature,
DELETE /awwan/api/execute?id=<string>
If the ID is exist, the execution will be cancelled and return HTTP
status 200 with the following body,
Content-Type: application/json
{
"code": 200,
}
Otherwise it will return HTTP status 404 with error message.
References: https://todo.sr.ht/~shulhan/awwan/9
|
|
Passing context allow the command Local or Play to be cancelled when
running in asynchronous mode, in this case when awwan run with WUI.
|
|
Using "-" as dummy date-time prefix make the test output quite hard
to read, especially since we use the same prefix "===" and "---" with Go
test output.
|
|
The execute directory is used as base directory of awwan during
testing APIExecute.
|
|
|
|
Previously, the magic line "#put" detect whether the source file is
encrypted or not automatically, so we did not need to put ".vault"
suffix in the source path.
This changes make it to be always explicit.
If we want to copy encrypted file than the source file must be the path
to encrypted file.
Implements: https://todo.sr.ht/~shulhan/awwan/7
|
|
In case we have a script that manage local host and remote server,
calling "play" on "#local" lines only always open the connection to remote
server.
To minimize opening unused connections, let the "#local" command works
on both commands. Its up to user which part of lines that they want
to execute on remote or local.
|
|
Previously, if the command output is "line1\n\nline2\n", the web output
it as
line1
line2
it should be
line1
line2
This fix the empty line not displayed in wui output.
|
|
|
|
Since each execution now logged in the file with ".log" extension,
there is no need to prefix it with script name again, because its
redundant.
|
|
In "/awwan/api/execute/tail" SSE endpoint, in order for client to be able
to reconnect and start streaming from the last know output, we need to
send the ID for each message that we send.
The ID is the index of Output in slice.
If client does not send Last-Event-ID, we send all Output from beginning,
otherwise, we send only message start from index in Last-Event-ID.
|
|
The new API is "GET /awwan/api/execute/tail" that implement Server-sent
events, not a normal GET request.
Its accept the query parameter "id" with value is the execution ID
from "/awwan/api/execute".
Once called with valid ID, it will streaming the command output
to client.
By using this new API, the WUI can receive the output of command
immediately without waiting for all commands to be completed.
Implements: https://todo.sr.ht/~shulhan/awwan/5
Signed-off-by: Shulhan <ms@kilabit.info>
|
|
Previously, the Execute endpoint wait for command execution to finish.
In case the command takes longer than proxy or server write timeout, it
will return with an timeout error to client.
In this changes, we generate an execution ID for each request and return
it immediately.
The next commit will implement HTTP endpoint to fetch the latest status
and/or output by execution ID.
References: https://todo.sr.ht/~shulhan/awwan/5
|
|
Previously, the ExecRequest from HTTP Execute endpoint changes the Script
value to the absolute script path in the system.
This changes fix this issue to minimize inconsistency between request
and response.
|
|
When user run "awwan serve", using web-user interface, any request to
fetch the content of "awwan.key" and "awwan.pass" should not allowed for
security reason, in case user want to serve awwan with others.
|
|
The "file" argument is optional, its define path to environment file.
If its empty it will be set to "awwan.env" in the current directory.
|
|
The env-get command get the value from environment files.
Syntax,
----
<key> [dir]
----
The "key" argument define the key where value is stored in environment
using "section:sub:name" format.
The "dir" argument is optional, its define the directory where environment
files will be loaded, recursively, from BaseDir to dir.
If its empty default to the current directory.
|
|
The env-set command set the value of environment file. Syntax,
<file> <key> <value>
The "file" argument define path to environment file.
The "key" argument define the key to be set using "section:sub:name"
format.
The "value" argument define the value key.
For example, to set the value for "name" under section "host" to
"myhost" in file "awwan.env" run
$ awwan env-set awwan.env host::name myhost
To set the value for key "pass" under section "user" subsection "database"
to value "s3cret" in file "awwan.env" run
$ awwan env-set awwan.env user:database:pass s3cret
|
|
In case awwan run with "serve" and we modify the ".ssh/config", the
changes does not detected by awwan because we only read ".ssh/config"
once we Awwan instance created.
This changes fix this issue by always loading SSH config everytime
the Play method executed so the user CLI and WUI has the same experiences.
|
|
Similar to the CLI, the HTTP API accept the path of vault file
and return the path to decrypted file.
|
|
Similar to the CLI, the HTTP API accept the path of file and return the
path to encrypted file.
|
|
If a multi lines command does not have spaces or have multiple
spaces, join them as is.
For example,
a\
b
should return the value as "ab", while
a \
b
should return "a b".
|
|
Instead of passing stdout and stderr as "io.Writer", pass the Request,
so we can log using the Request mlog.
While at it, return error from sshClient rmdirAll so the caller can log
the error.
|
|
Previously, if there is any error from Local or Play before any statement
get executed it will not logged to log, also the Request close() is
not called since we put it as defer in the middle.
This changes fix this by moving down error handler into single exit
goto label.
|
|
When the script executed, log the script and line number to be executed
with "=== BEGIN", and when its finished, log the end of it with "=== END".
This is to make the log more traceable.
|
|
For each script execution, a file suffixed with ".log" will be created
in the same directory with the same name as script file.
For example, if the script is path is "a/b/c.aww" then the log file
would named "a/b/c.aww.log".
This is to provides history and audit in the future.
|
|
By using "mlog.MultiLogger" every output or error can be written to
stdout/stderr and additional log writer that can collect both of them,
buffered and returned to the caller.
This changes simplify the HttpResponse to use only single output that
combine both stdout and stderr.
|
|
Previously, if the source file to be copied is not exist, awwan will
output only error for the ".vault" file, twice, for example
!!! Copy: <source>.vault: open <source>.vault not exist
Local: Copy: <source>.vault: open <source>.vault not exist
This changes make the first line output to print the original source
file first, the non-ecrypted one, and then followed by encrypted one,
??? loadFileInput "<source>": not exist
Local: Copy "<source>.vault": not exist
|
|
The magic command "#local" define the command to be executed using
shell in local environment.
Its have effect and can only be used in script that executed using
"play".
In script that is executed using "local" it does nothing.
|
|
When script with magic command "#get!" or "#put!" executed using "play"
command, one can changes the owner and/or permission mode by setting
the user/group and permission bits after the magic command, for example,
#get!user:group+0600 src dst
Will changes the owner of dst in local into "user:group" with permission
"0600", while
#put!user:group+0600 src dst
Will changes the owner of dst in remote into "user:group" with permission
"0600".
|
|
In remote environment, using magic command "#get:" or "#put:" with owner
and mode like "#get:$OWNER+$MODE" or "#put:$OWNER+MODE" will changes
the file owner to $USER or $GROUP and/or permission to $MODE.
The file owner will not works if user does not have permission.
|
|
In this directory we setup awwan workspace, with one remote server called
"awwanssh.test".
The SSH connection to remote server "awwanssh.test" is defined in
".ssh/config".
|
|
In local environment, using magic command "#get!" or "#put!" with owner
and mode set, like "#get:$USER:$GROUP+$MODE" or "#put:$USER:$GROUP+MODE",
will changes the file owner to $USER or $GROUP and/or permission to $MODE.
|
|
In local environment, using magic command "#get" or "#put" with mode
like "#get:$USER:$GROUP+$MODE" or "#put:$USER:$GROUP+MODE" will changes
the file owner to $USER or $GROUP and/or permission to $MODE.
The file owner does not works if user does not have permission to changes
the owner.
|
|
|
|
|
|
Instead of breaking the statement when its failed to execute, return
the error to the caller, Local.
|
|
This changes minimize code duplication when parsing magic command
between "#get:" and "#get!" using single function parseStatementGetPut.
In the returned Statement, we changes where to store the source argument
into args[0] instead of in cmd for better readability and minimize
confusion in Copy/SudoCopy.
While at it, we add unit test for "#get:".
Unit test for "#get!" is not possible right now, because it will prompt
for password.
|
|
On new cloned repository, running the test will fail when using symlink,
0 - Decrypt: DecryptOaep: crypto/rsa: decryption error
0 + Decrypt: open testdata/decrypt-wrong-privatekey/.awwan.env.vault:
no such file or directory
|
|
In the environment where passphrase cannot be inputted manually, for
example, automatic integration or deployment, we need some mechanism
where awwan can be executed to copy or decrypt the encrypted file.
The option is by reading plain passphrase from file named "awwan.pass"
inside the ".ssh" directory.
If its exists and not empty, awwan will not prompt for passphrase from
terminal, instead use the content of that file as passhprase.
|
|
This is to minimize log length in stdout and stderr, which make it
more readable.
|