-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes related to Debian packaging work #86
Conversation
run.sh
Outdated
@@ -16,14 +16,20 @@ while [ -n "$1" ]; do | |||
done | |||
|
|||
SDC_HOME=${SDC_HOME:-$(mktemp -d)} | |||
DB_HOME=$SDC_HOME/data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic should be kept inside the app. There should only be a single injection of SDC_HOME
, and the app should figure everything else out from there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This helps to make sure that I am creating the directory structure properly, as I need that directory structure to create the DB file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All of this logic is inside the app. Doing it in two places runs the risk of us relying on something we shouldn't.
run.sh
Outdated
from securedrop_client.models import Base, make_engine | ||
Base.metadata.create_all(make_engine("$SDC_HOME")) | ||
EOF | ||
./createdb.py $DB_HOME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's fine to leave this as a here-doc since run.sh
is a dev-only tool to help people with launching the app while iterating. Additionally, this doesn't solve the "bootstrap at first run" ticket.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bootstrapping in production is handled by the securedrop-client
script.
@@ -16,6 +16,8 @@ | |||
# add your model's MetaData object here | |||
# for 'autogenerate' support | |||
sys.path.insert(0, path.realpath(path.join(path.dirname(__file__), '..'))) | |||
# This path is purely for alembic to work on the packaged application | |||
sys.path.insert(1, "/opt/venvs/securedrop-client/lib/python3.5/site-packages") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this necessary? Shouldn't we keep the alembic directory in a fix position relative to the app? The first path insertion should catch every case, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because this is how it can help in packaging. We need static config files to able to package them easily and without any dynamic magic at runtime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't understand. What is the exact case that you're describing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The first path is for the development environment, and the second path is for the case where we are running using Debian package. The alembic
directory is installed in the standard /usr/share/securedrop-workstation/
location.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why isn't the alembic directory placed somewhere relative to the source code? Wouldn't that be simpler?
|
||
[alembic] | ||
# path to migration scripts | ||
script_location = /usr/share/securedrop-client/alembic |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we're going to be running alembic, we shouldn't be using a hard coded value you like this. We should use a template and a %%ALEMBIC_PATH%%
or something similar to replace the values in a pre-alembic
step.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to help the Debian packaging. All packaged applications (as far as I know) in Fedora land also uses the same idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, but the alembic.ini
is useless without this line
sqlalchemy.url = sqlite:////path/to/database.sqlite
The app at boot could pull an alembic.ini.tmpl
from /var/lib/
or /usr/share
and then inject that value before running alembic upgrade head
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is here for the default path in the Debian package https://github.com/freedomofpress/securedrop-client/pull/86/files#diff-3f5cd7c244dcadbe672e3644a1f283bdR38
files/client.ini
Outdated
@@ -0,0 +1,3 @@ | |||
[client] | |||
homedir=~/.securedrop_client | |||
use_securedrop_proxy=True |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: missing newline at EOF
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, will add this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will wait for all the other issues to be discussed and resolved, I will fix at the very end :)
securedrop_client/app.py
Outdated
@@ -104,6 +105,9 @@ def arg_parser() -> ArgumentParser: | |||
type=expand_to_absolute, | |||
help=('SecureDrop Client home directory for storing files and state. ' | |||
'(Default {})'.format(DEFAULT_SDC_HOME))) | |||
parser.add_argument( | |||
'-p', '--proxy', action='store_true', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm somewhat not a fan of using single letters for boolean values because of the chances for confusion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can remove that.
securedrop_client/app.py
Outdated
@@ -120,6 +124,7 @@ def start_app(args, qt_args) -> None: | |||
- configure the client (logic) object. | |||
- ensure the application is setup in the default safe starting state. | |||
""" | |||
print(args.proxy) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like you left a debug print
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, will be removed.
securedrop_client/app.py
Outdated
@@ -150,7 +156,14 @@ def start_app(args, qt_args) -> None: | |||
|
|||
|
|||
def run() -> None: | |||
config_file = "/etc/securdrop-client/client.ini" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not be configuring from /etc
. Configs should be at the root of sdc_home
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should configure with /etc/
as that will be useful to update through the Debian package. The package will be installed at the template, and we should have the default values already in the config for the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a little confused on the goals then. Is the securedrop-client
so hyper targeted toward Qubes that we aren't going to work in having it operate anywhere else ever? Or should we use some patterns that allow us to be able to run it in other linux-y environments? Because what I don't like about SecureDrop core is that the Debian packages are useless without running ansible
first. IMO configuration should be entirely outside the Debian side and use defaults in the Python code to handle the no-config cases.
os.path.exists(config_file): # pragma: no cover | ||
config = configparser.ConfigParser() | ||
config.read(config_file) | ||
args.sdc_home = config["client"]["homedir"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you overriding the sdc_home
after reading a config from sdc_home
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am reading the config from /etc/securdrop-client/client.ini
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I still think this make no sense. The client is passed a sdc_home
, then we read another value, then we sed that other value to sdc_home
. I feel like this isn't a good pattern and is kind confusing.
config = configparser.ConfigParser() | ||
config.read(config_file) | ||
args.sdc_home = config["client"]["homedir"] | ||
args.proxy = config["client"]["use_securedrop_proxy"] | ||
# reinsert the program's name | ||
qt_args.insert(0, 'securedrop-client') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More generally, I think that the CLI parsing should all happen outside the app, and then we pass those as args to start_app
(or run_app
, whatever the name was). In side there, we handle the logic of how to include values from the configs. I think reusing the Namespace
from argparse
as the "master config" seems wrong. We might want to have a Config
class that does all this logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am going to leave this for a future PR.
a9c9e5c
to
1dd9570
Compare
Notes from the video call with @heartsucker . @heartsucker's point of viewHaving any configuration file under @kushaldas's point of viewI thought (as a packager) that any configuration should be under Another option is to keep |
run.sh
Outdated
mkdir -p $LOGS_HOME | ||
chmod 0700 $SDC_HOME | ||
chmod 0700 $DB_HOME | ||
chmod 0700 $LOGS_HOME |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again isn't this also done in the app itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we want to have the db file as ~/.securedrop_client/data
, if we have it under ~/.securedrop_client/
then I can remove these lines (keeping the lines only for $SDC_HOME
). As the database must come up (using Alembic) before the application starts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true, we gotta create the database before starting the application - but see my comment here, we can at least delegate these folder creation to the application (the less logic we have duplicated the better)
securedrop_client/logic.py
Outdated
@@ -85,7 +85,8 @@ class Client(QObject): | |||
|
|||
finish_api_call = pyqtSignal() # Acknowledges reciept of an API call. | |||
|
|||
def __init__(self, hostname, gui, session, home: str) -> None: | |||
def __init__(self, hostname, gui, session, | |||
home: str, proxy: bool = False) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
proxy
should be True if the default application is Qubes first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay.
files/alembic.ini
Outdated
# are written from script.py.mako | ||
# output_encoding = utf-8 | ||
|
||
sqlalchemy.url = sqlite:////home/user/.securedrop_client/data/svs.sqlite |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note right now the db path is:
/home/user/.securedrop_client/svs.sqlite
(which I think is actually good as the data
directory contains only downloaded messages / files)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I misread this line
~/.securedrop_client/data -> config, database, files (submissions, messages)
So, I will modify to change the path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry that's my bad :-(
e2d3aca
to
187c5be
Compare
Updates config locations and making proxy default for Client Now we have all the configurations under The database file is now located at ~/securedrop_client/ Based on the PR review comments from @heartsucker @redshiftzero |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was able to successfully build a deb package on this, thanks for this @kushaldas and for making the changes!
I will flag that in the coming weeks we do need to invest some time into build automation, as building deb packages manually like I just did is a bit tedious and error-prone
anyway, for now I think we should continue onwards - @heartsucker - even if you have no blocking issues here can you file followups for anything else that you think should be addressed/discussed packaging wise for beta? (reason is that beta is when this will get installed in news orgs so we really need to have anything that impacts the long term maintenance plan nailed down - if all goes well we'll be supporting those beta installations for maybe years)
Just got off a call with Jen were were talked about this PR. Here's my issues.
The only config that would need to be shipped with the package so far is the To auto-handle configs and load a local config if present, we should probably have a If we have a "master" config in * please not Last, I don't want to have to rely on Addressing Jen's concern, there should be a |
One thing. Can you remove the edit: Just kidding, ignore this. |
@@ -0,0 +1,3 @@ | |||
[client] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use .json
as the config type because it allows for deeper nesting, lists, and also ops tools have nice functions for mangling/merging JSON?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we stick with ini for simplicity for now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure
os.path.exists(config_file): # pragma: no cover | ||
config = configparser.ConfigParser() | ||
config.read(config_file) | ||
args.sdc_home = config["client"]["homedir"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I still think this make no sense. The client is passed a sdc_home
, then we read another value, then we sed that other value to sdc_home
. I feel like this isn't a good pattern and is kind confusing.
os.path.exists(config_file): # pragma: no cover | ||
config = configparser.ConfigParser() | ||
config.read(config_file) | ||
args.sdc_home = config["client"]["homedir"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is done to make sure that we use the whatever values are there in the config file. This part is to be used only after installing via debian package, and we can improve this in future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have a hardcoded home directory in Qubes, so we're using that hard coded value to read a hardcoded config to then switch the home to something else hardcoded. This seems like a lot of indirection.
Dismissing review to unblock. I'm generally fine with this, for the alpha, but there's things I still think should be changed.
import sys | ||
|
||
from securedrop_client.models import Base, make_engine | ||
Base.metadata.create_all(make_engine(sys.argv[1])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the comment got lost, but I still think this is better as a here-doc since it's just for the dev env and it's simple enough to just shove into the bash script.
We need these config files for the Debian packaging. The securedrop-client script will make sure that we have the right database structure, or will apply the migration as required. We will need a future PR to fix ./run.sh to work with the changes related to Debian packaging.
We are now using the similar directory structure in run.sh and also in securdrop-client. We are also using the createdb.py to create the db in the local environment.
Use ./run.sh --proxy to connect to the proxy vm.
Now we have all the configurations under /usr/share/securedrop-client/ including the alembic.ini file. The database file is now located at ~/securedrop_client/ Based on the PR review comments.
187c5be
to
c331034
Compare
hey @heartsucker, I've filed #97 and added it to the beta milestone so we can continue this discussion there, and please feel free to open other issues as followups to this. For now, merging so that we resolve the must-do issues for alpha |
Add link to Code of Conduct to README
Fixes #2 #30 #31.
Now we have
securedrop-client
script, which will execute the steps required to run the application following all standard default paths (from the Debian package).We are trying to apply any
alembic
revision at the start of the tool, that way, when ever the user restarts the application, it will have the right database structure.One can improve the
./run.sh
in future. For now I kept it as simple as possible.How to test?
./run.sh
to use the tool like previously and connect to the server using web API./run.sh -p
to connect using the Proxy VM.