dbcli / litecli

CLI for SQLite Databases with auto-completion and syntax highlighting
https://litecli.com
BSD 3-Clause "New" or "Revised" License
2.06k stars 67 forks source link

Litecli crashes in non root containerized environment without home directory #172

Closed ncrmro closed 4 months ago

ncrmro commented 5 months ago

Looks like on startup litecli assumes it should be able to create the home directory of the current user. There is no home directory for this user and the filesystem is for the most part read only except for a few volumes. I can make a PR but wondering if anyone here has any thoughts.

This is in a nonroot container.

litecli /database/sqlite3.db
Traceback (most recent call last):
  File "/usr/local/bin/litecli", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/litecli/main.py", line 921, in cli
    litecli = LiteCli(
              ^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/litecli/main.py", line 78, in __init__
    c = self.config = get_config(liteclirc)
                      ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/litecli/config.py", line 60, in get_config
    write_default_config(default_config, liteclirc_file)
  File "/usr/local/lib/python3.11/dist-packages/litecli/config.py", line 42, in write_default_config
    ensure_dir_exists(destination)
  File "/usr/local/lib/python3.11/dist-packages/litecli/config.py", line 30, in ensure_dir_exists
    os.makedirs(parent_dir)
  File "<frozen os>", line 215, in makedirs
  File "<frozen os>", line 215, in makedirs
  File "<frozen os>", line 225, in makedirs
PermissionError: [Errno 13] Permission denied: '/nonexistent'
amjith commented 5 months ago

Litecli writes the default config file to ~/.config/litecli/config and it also uses that location to store the log files.

Can you try copying the liteclirc file into a location and launch litecli using:

litecli --liteclirc <PATH-TO-RC>

and see if that works?

ncrmro commented 5 months ago

@amjith same issue when

litecli --liteclirc /database/liteclirc

Traceback (most recent call last):
  File "/usr/local/bin/litecli", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/litecli/main.py", line 921, in cli
    litecli = LiteCli(
              ^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/litecli/main.py", line 123, in __init__
    self.initialize_logging()
  File "/usr/local/lib/python3.11/dist-packages/litecli/main.py", line 242, in initialize_logging
    ensure_dir_exists(log_file)
  File "/usr/local/lib/python3.11/dist-packages/litecli/config.py", line 30, in ensure_dir_exists
    os.makedirs(parent_dir)
  File "<frozen os>", line 215, in makedirs
  File "<frozen os>", line 215, in makedirs
  File "<frozen os>", line 225, in makedirs
PermissionError: [Errno 13] Permission denied: '/nonexistent'
amjith commented 5 months ago

Can you try editing the log file location in your literc file?

https://github.com/dbcli/litecli/blob/main/litecli/liteclirc#L19

Set it to a location that is available in the docker container and see if that gets around it?

ncrmro commented 4 months ago

After creating the default, this ends up giving me.

nextjs@f095bfc4d0fe:/app$ litecli --liteclirc /tmp/liteclirc --logfile /tmp/txt.log
Traceback (most recent call last):
  File "/usr/local/bin/litecli", line 8, in <module>
    sys.exit(cli())
             ^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/litecli/main.py", line 921, in cli
    litecli = LiteCli(
              ^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/litecli/main.py", line 78, in __init__
    c = self.config = get_config(liteclirc)
                      ^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/litecli/config.py", line 62, in get_config
    return load_config(liteclirc_file, default_config)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/litecli/config.py", line 21, in load_config
    cfg.merge(ConfigObj(expanduser(usr_cfg), interpolation=False, encoding="utf-8"))
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/configobj/__init__.py", line 1229, in __init__
    self._load(infile, configspec)
  File "/usr/local/lib/python3.11/dist-packages/configobj/__init__.py", line 1318, in _load
    raise error
configobj.ConfigObjError: Parsing failed with several errors.
First error at line 129.
nextjs@f095bfc4d0fe:/app$ 
amjith commented 4 months ago

You're right that it shouldn't crash when it can't create the necessary folders. It'll be nice to print a warning that it failed to create them when the app starts so the user is aware.

If you're interested in contributing a PR, I'll be happy to merge it. If not, I'll take some time this upcoming week to implement it. Let me know what you prefer.

amjith commented 4 months ago

Can you try this branch and tell me if it work?

pip install -U https://github.com/dbcli/litecli/archive/refs/heads/optional-config.zip
ncrmro commented 4 months ago

@amjith I can confirm this works ty!!!