Skip to content
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

SSH provider: Cannot browse non-Linux hosts (FreeBSD, macOS, etc); invalid stat command flags #209

Open
s-daveb opened this issue Dec 2, 2024 · 5 comments
Labels
enhancement/request New feature or request Provider Issue with a _remote_ (core) provider SSH SSH Provider
Milestone

Comments

@s-daveb
Copy link

s-daveb commented Dec 2, 2024

Good morning,

I love what you're trying to do, and I'm noticing that there is some partial support for non-Linux hosts... when I try to connect with :Neotree remote to the FreeBSD Hosts on my .ssh/config, I see a small FreeBSD Icon appear next to the host name, and nothing else happens.

I've already got passwordless login using public-private key encryption and it works from any standard terminal using SSH or MOSH.

However, no files appear in the Neotree file panel, as opposed to a Linux system:
Screenshot 2024-12-02 at 8 40 25 AM

When I check :NMlogs, I find the following, with an error message regarding the 'stat' command:
Received non-0 exit code while trying to stat ssh://moho/// { error = "stat: illegal option -- cusage: stat [-FLnq] [-f format | -l | -r | -s | -x] [-t timefmt] [file|handle ...]",

see the full log below:

[2024-12-02 08:37:58] [SID: eknqhzxmwseklup] [Logger: system] [Level: TRACE]     -- ...id/.local/share/nvim/lazy/netman.nvim/lua/netman/api.lua:asp:628	Performing ASP (prove) check on `ssh.read_a` -> Was a proper async handle returned? false
[2024-12-02 08:37:58] [SID: eknqhzxmwseklup] [Logger: system] [Level: WARN]      -- ...id/.local/share/nvim/lazy/netman.nvim/lua/netman/api.lua:asp:630	Provider ssh did not return a proper async handle after async request. Removing read_a from it for the remainder of this session
[2024-12-02 08:37:58] [SID: eknqhzxmwseklup] [Logger: system] [Level: TRACE2]   -- ...id/.local/share/nvim/lazy/netman.nvim/lua/netman/api.lua:asp:657	Passing result data to callback ...share/nvim/lazy/netman.nvim/lua/netman/providers/ssh.lua:2025: attempt to index local 'stat' (a nil value)
[2024-12-02 08:37:58] [SID: eknqhzxmwseklup] [Logger: system] [Level: INFO]      -- ...id/.local/share/nvim/lazy/netman.nvim/lua/netman/api.lua:_process_provider_response:676	Provider `ssh` failed to include success in response. Adding 'success=false' to response

[2024-12-02 08:38:03] [SID: eknqhzxmwseklup] [Logger: system] [Level: DEBUG]    -- ...local/share/nvim/lazy/netman.nvim/lua/netman/ui/init.lua:nil:25	Comparing  to old state 
[2024-12-02 08:38:03] [SID: eknqhzxmwseklup] [Logger: system] [Level: DEBUG]    -- ...local/share/nvim/lazy/netman.nvim/lua/netman/ui/init.lua:nil:25	Comparing  to old state 
[2024-12-02 08:38:18] [SID: eknqhzxmwseklup] [Logger: system] [Level: DEBUG]    -- ...local/share/nvim/lazy/netman.nvim/lua/netman/ui/init.lua:nil:25	Comparing  to old state 
[2024-12-02 08:38:18] [SID: eknqhzxmwseklup] [Logger: system] [Level: DEBUG]    -- ...local/share/nvim/lazy/netman.nvim/lua/netman/ui/init.lua:nil:25	Comparing  to old state 
[2024-12-02 08:38:30] [SID: eknqhzxmwseklup] [Logger: provider] [Level: TRACE]    -- ...share/nvim/lazy/netman.nvim/lua/netman/providers/ssh.lua:__index:238	Checking OS For Host moho
[2024-12-02 08:38:31] [SID: eknqhzxmwseklup] [Logger: provider] [Level: TRACE2]   -- ...share/nvim/lazy/netman.nvim/lua/netman/providers/ssh.lua:run_command:398	{
  cmd_pieces = { "ssh", "-o", "ControlMaster=auto", "-o", 'ControlPath="/Users/sdavid/.cache/nvim/netman/tmp//%C"', "-o", "ControlPersist=10", "moho", "/bin/sh -c 'cat /etc/*release* | grep -E \"^NAME=\" | cut -b 6-'" },
  command = "ssh -o ControlMaster=auto -o ControlPath=\"/Users/sdavid/.cache/nvim/netman/tmp//%C\" -o ControlPersist=10 moho /bin/sh -c 'cat /etc/*release* | grep -E \"^NAME=\" | cut -b 6-'",
  elapsed_time = 548358750,
  elapsed_time_ml = 548.35875,
  exit_code = 0,
  opts = {
    STDERR_JOIN = "",
    STDOUT_JOIN = ""
  },
  pid = 33317,
  signal = 0,
  stderr = "",
  stdout = "FreeBSD"
}
[2024-12-02 08:38:31] [SID: eknqhzxmwseklup] [Logger: consumer] [Level: TRACE]     -- ...re/nvim/lazy/netman.nvim/lua/netman/ui/neo-tree/init.lua:open_uri:416	Opening Node: ssh://moho///
[2024-12-02 08:38:31] [SID: eknqhzxmwseklup] [Logger: system] [Level: INFO]     -- ...id/.local/share/nvim/lazy/netman.nvim/lua/netman/api.lua:read:857	Reaching out to ssh to read ssh://moho///
[2024-12-02 08:38:31] [SID: eknqhzxmwseklup] [Logger: system] [Level: TRACE]     -- ...id/.local/share/nvim/lazy/netman.nvim/lua/netman/api.lua:asp:609	Performing ASP (ask) check on ssh -> Was async requested? true
[2024-12-02 08:38:31] [SID: eknqhzxmwseklup] [Logger: system] [Level: TRACE]     -- ...id/.local/share/nvim/lazy/netman.nvim/lua/netman/api.lua:asp:613	Performing ASP (say) check on ssh -> Is `connect_host_a` available? false
[2024-12-02 08:38:31] [SID: eknqhzxmwseklup] [Logger: system] [Level: TRACE]     -- ...id/.local/share/nvim/lazy/netman.nvim/lua/netman/api.lua:asp:616	Attempting to run `ssh.connect_host` synchronously
[2024-12-02 08:38:31] [SID: eknqhzxmwseklup] [Logger: provider] [Level: TRACE2]   -- ...share/nvim/lazy/netman.nvim/lua/netman/providers/ssh.lua:run_command:398	{
  cmd_pieces = { "ssh", "-o", "ControlMaster=auto", "-o", 'ControlPath="/Users/sdavid/.cache/nvim/netman/tmp//%C"', "-o", "ControlPersist=10", "moho", "stat -L -c MODE=%f,BLOCKS=%b,BLKSIZE=%B,MTIME_SEC=%X,USER=%U,GROUP=%G,INODE=%i,PERMISSIONS=%a,SIZE=%s,TYPE=%F,NAME=%n /" },
  command = 'ssh -o ControlMaster=auto -o ControlPath="/Users/sdavid/.cache/nvim/netman/tmp//%C" -o ControlPersist=10 moho stat -L -c MODE=%f,BLOCKS=%b,BLKSIZE=%B,MTIME_SEC=%X,USER=%U,GROUP=%G,INODE=%i,PERMISSIONS=%a,SIZE=%s,TYPE=%F,NAME=%n /',
  elapsed_time = 0,
  elapsed_time_ml = 0,
  opts = {
    ASYNC = true,
    EXIT_CALLBACK = <function 1>,
    STDERR_JOIN = ""
  },
  pid = 33334,
  stderr = {},
  stdout = {}
}
[2024-12-02 08:38:31] [SID: eknqhzxmwseklup] [Logger: provider] [Level: TRACE]    -- ...share/nvim/lazy/netman.nvim/lua/netman/providers/ssh.lua:callback:1353	{
  cmd_pieces = { "ssh", "-o", "ControlMaster=auto", "-o", 'ControlPath="/Users/sdavid/.cache/nvim/netman/tmp//%C"', "-o", "ControlPersist=10", "moho", "stat -L -c MODE=%f,BLOCKS=%b,BLKSIZE=%B,MTIME_SEC=%X,USER=%U,GROUP=%G,INODE=%i,PERMISSIONS=%a,SIZE=%s,TYPE=%F,NAME=%n /" },
  command = 'ssh -o ControlMaster=auto -o ControlPath="/Users/sdavid/.cache/nvim/netman/tmp//%C" -o ControlPersist=10 moho stat -L -c MODE=%f,BLOCKS=%b,BLKSIZE=%B,MTIME_SEC=%X,USER=%U,GROUP=%G,INODE=%i,PERMISSIONS=%a,SIZE=%s,TYPE=%F,NAME=%n /',
  elapsed_time = 50105250,
  elapsed_time_ml = 50.10525,
  exit_code = 1,
  opts = {
    ASYNC = true,
    EXIT_CALLBACK = <function 1>,
    STDERR_JOIN = ""
  },
  pid = 33334,
  signal = 0,
  stderr = "stat: illegal option -- cusage: stat [-FLnq] [-f format | -l | -r | -s | -x] [-t timefmt] [file|handle ...]",
  stdout = {}
}
[2024-12-02 08:38:31] [SID: eknqhzxmwseklup] [Logger: provider] [Level: WARN]     -- ...share/nvim/lazy/netman.nvim/lua/netman/providers/ssh.lua:callback:1373	Received non-0 exit code while trying to stat ssh://moho/// {
  error = "stat: illegal option -- cusage: stat [-FLnq] [-f format | -l | -r | -s | -x] [-t timefmt] [file|handle ...]",
  exit_code = 1,
  locations = { "/" },
  stdout = {}
}
[2024-12-02 08:38:31] [SID: eknqhzxmwseklup] [Logger: system] [Level: TRACE2]   -- ...id/.local/share/nvim/lazy/netman.nvim/lua/netman/api.lua:asp:657	Passing result data to callback {
  message = {
    message = "Received non-0 exit code while trying to stat ssh://moho///"
  },
  success = false
}
@s-daveb
Copy link
Author

s-daveb commented Dec 2, 2024

Since it looks like it's just a malformed stat call, I might be able to submit a pull request, but I have to get through my day job first. I'll try to see if I have the spare time to fix it.

@miversen33
Copy link
Owner

I don't "officially" support non-linux/non-windows operating systems. That is mostly because I don't have one laying around to test on.

That said, I am more than happy to accept a PR :)

Some things you are going to want to look for
Stat flag names are defined in providers/ssh.lua:45-59 and the actual flags themselves are defined in providers/ssh.lua:1392-1396.

The actual format flags on providers/ssh.lua:1395 are very specifically laid out. If you need to change the flags used here, feel free for your PR but we will need to review them to ensure they work on Linux based OS's as well.

A note (I don't remember if its documented or not), the stat flags are setup as KEY=VALUE, where KEY is found (as a value) in SSH.CONSTANTS.STAT_FLAGS, and VALUE is the valid format key used in stat -c.

Do not change the last flag in the stat format (I don't remember if the logic is still there, but at one time the stat output parser expected NAME to be the last item in the output).

Do not add a space between KEY, =, VALUE, ,. It is important for the parser that you match your new flags exactly as the other ones are done.

Lastly, if it proves impossible for Linux and BSD to live together in this provider (IE, you can't just slightly modify the stat flags), there is another route we can take to support BSD. If you check out providers/ssh.lua:189-195, you can see how we differentiate between busybox and GNU tar. We could do something similar for stat and BSD (though we would need to do more retrofitting since stat doesn't use any sort of retrofitting currently).

For that (if we need to go that route), check out providers/ssh:251-327 for reference. We would not use this function but we could create something similar for stat to "other" clients that aren't linux (or maybe that aren't GNU instead?)

Feel free to tinker, if you have issues or questions, please ping me :)

@miversen33
Copy link
Owner

After looking at the error you provided, I am pretty sure we won't be able to "easily" update the stat flags to work with BSD's flavor of stat. So in order to get support for BSD, we are going to need to go the last route I mentioned above (adding stat flavors like we do for tar).

If I have time tonight, I will see if I can spin up a BSD vm to play with that a bit, though I would prefer a PR from someone with experience using BSD.

@s-daveb
Copy link
Author

s-daveb commented Dec 2, 2024

Thank you. I'll try to do the same, if I have the time. I've never used stat directly in *bsd but I have administered a few systems and deployed applications on it, so I'm familiar with their documentation. (It's top-notch in my opinion ;))

Thanks for the pointers. Should definitely help.

@miversen33 miversen33 added enhancement/request New feature or request Provider Issue with a _remote_ (core) provider SSH SSH Provider labels Dec 2, 2024
@miversen33 miversen33 added this to the Backlog milestone Dec 2, 2024
@miversen33
Copy link
Owner

I have setup a FreeBSD VM and have tested a bit to figure out how to approach this. I am working through an implementation that extends stat to allow for FreeBSD (and potentially Mac if its needed?).

If you are still playing with this, you will want to use the following stat command flags
'-L', '-f', 'MODE=%Xp,BLOCKS=%b,BLKSIZE=%k,MTIME_SEC=%m,USER=%Su,GROUP=%Sg,INODE=%i,PERMISSIONS=%OLp,SIZE=%z,TYPE=%HT,NAME=%N'

This gets pretty close to what we are out putting with the linux version of stat. The main difference (from what I can tell) is that the 'TYPE' is coming back slightly differently than it does in Linux. I haven't dug too deep into that part of the code but I seem to recall there is quite a bit of data normalization that happens so I am not super worried about that.

Really, this means that we just need to put a switch on host connection that checks the host OS and if its FreeBSD (Or some other BSD variants?), then we set the flags to be what I have listed above. Nothing after gathering the results should have to be modified

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement/request New feature or request Provider Issue with a _remote_ (core) provider SSH SSH Provider
Projects
None yet
Development

No branches or pull requests

2 participants