Trellis db open: "Error unmarshaling db credentials JSON file: unexpected end of JSON input"

I’m updating an ancient Roots install to use Trellis, and I created a new Trellis app. When I try to do trellis db open --app=sequel-ace development I get the error:

Error unmarshaling db credentials JSON file: unexpected end of JSON input

I followed the Discourse advice about how to set up Sequel Ace, but nothing seems to work. Any advice?

The db open command generates a temporary internal Ansible playbook and executes it to generate a JSON file and obviously that part isn’t working; it also makes it hard to debug.

The only real way to reproduce what trellis-cli is doing and get better output is to create the playbook manually and run it.

  1. In your Trellis directory, create a file called db.yml with this contents:
---
- name: 'Trellis CLI: Dump database credentials'
  hosts: web:&{{ env }}
  remote_user: "{{ web_user }}"
  gather_facts: false
  connection: local
  tasks:
    - name: Dump database credentials
      template:
        src: db_credentials.json.j2
        dest: "{{ dest }}"
        mode: '0600'
      with_dict: "{{ wordpress_sites }}"
      when: item.key == site
  1. create a file called db_credentials.json.j2 with this contents:
{
  "web_user": "{{ web_user }}",
  "ansible_host": "{{ ansible_host }}",
  "ansible_port": {{ ansible_port | default(22) }},
  "db_user": "{{ site_env.db_user }}",
  "db_password": "{{ site_env.db_password }}",
  "db_host": "{{ site_env.db_host }}",
  "db_name": "{{ site_env.db_name }}",
  "wp_env": "{{ site_env.wp_env }}"
}
  1. Run this command with your site name in place of example.com: trellis exec ansible-playbook db.yml -e "env=development -e site=example.com -e dest=test.json"
  2. Paste the output of that command
  3. Paste the output of test.json

In a successful case, it looks like this:

{
  "web_user": "vagrant",
  "ansible_host": "192.168.56.5",
  "ansible_port": 22,
  "db_user": "example_com",
  "db_password": "example_dbpassword",
  "db_host": "localhost",
  "db_name": "example_com_development",
  "wp_env": "development"
}

Hi! I ran that command and it printed this:

[WARNING]: Unable to parse /Users/davidham/ansible_hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: web
[WARNING]: Could not match supplied host pattern, ignoring: development

Looks like I need an ansible_hosts?

Does your project have a hosts directory like this: trellis/hosts at master · roots/trellis · GitHub ?

It does, here is development:

# List each machine only once per [group], even if it will host multiple sites.

[development]
192.168.56.5

[web]
192.168.56.5

I also added that IP to my ~/.ssh/config, following your earlier Discourse post.

Can you paste the contents of your ansible.cfg file in the Trellis dir?

yup, here it is:

[defaults]
callback_plugins    = ~/.ansible/plugins/callback:/usr/share/ansible/plugins/callback:lib/trellis/plugins/callback
filter_plugins      = ~/.ansible/plugins/filter:/usr/share/ansible/plugins/filter:lib/trellis/plugins/filter
force_color         = True
force_handlers      = True
inventory           = hosts
nocows              = 1
roles_path          = vendor/roles
vars_plugins        = ~/.ansible/plugins/vars:/usr/share/ansible/plugins/vars:lib/trellis/plugins/vars
pipelining          = True
vault_password_file = .vault_pass

[ssh_connection]
ssh_args = -o ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s -o HostKeyAlgorithms=ssh-ed25519-cert-v01@openssh.com,ssh-rsa-cert-v01@openssh.com,ssh-ed25519,ssh-rsa
retries  = 1

Sorry, one more request. Can you paste the output from trellis exec ansible-playbook --version?

Gosh, don’t be sorry, I’m very grateful for the help!

$ trellis exec ansible-playbook --version
ansible-playbook [core 2.14.3]
  config file = /Users/davidham/projects/davidham.com/davidham.com/trellis/ansible.cfg
  configured module search path = ['/Users/davidham/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/davidham/projects/davidham.com/davidham.com/trellis/.trellis/virtualenv/lib/python3.11/site-packages/ansible
  ansible collection location = /Users/davidham/.ansible/collections:/usr/share/ansible/collections
  executable location = /Users/davidham/projects/davidham.com/davidham.com/trellis/.trellis/virtualenv/bin/ansible-playbook
  python version = 3.11.1 (main, Jan  7 2023, 11:00:45) [Clang 14.0.0 (clang-1400.0.29.202)] (/Users/davidham/projects/davidham.com/davidham.com/trellis/.trellis/virtualenv/bin/python3)
  jinja version = 3.1.2
  libyaml = True

None of this makes sense :thinking: I was able to replicate the error you got by renaming my hosts directory to something else:

trellis exec ansible-playbook db.yml -e "env=development -e site=example.com -e dest=test.json"
[WARNING]: Unable to parse /Users/scottwalkinshaw/dev/trellis/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: web
[WARNING]: Could not match supplied host pattern, ignoring: development

But notice that it’s properly looking for /Users/scottwalkinshaw/dev/trellis/hosts unlike yours, which had /Users/davidham/ansible_hosts. It should be /Users/davidham/projects/davidham.com/davidham.com/trellis/hosts

And your version output + config otherwise looks correct and as I’d expect.

/Users/davidham/ansible_hosts isn’t even a default location that Ansible looks in from what I can tell. At this point, I have no ideas unfortunately. Try searching your entire system for ansible_hosts?

One thing which should temporarily solve it: use the ANSIBLE_INVENTORY env var.

ANSIBLE_INVENTORY=/Users/davidham/projects/davidham.com/davidham.com/trellis/hosts trellis db open --app=sequel-ace development

Aaaaaah! I had a setting for ANSIBLE_INVENTORY deep in my dotfiles from god knows when; I unset that and trellis db open was able to proceed.

Here’s a new one though, it opens Sequel Ace but can’t connect, gives me this:

This is with 192.168.56.5 added after the hostname in known_hosts, like this:

Host davidham.test 192.168.56.5

I am able to ssh vagrant@davidham.test, incidentally; not sure whats missing for the tunnel.

Thanks so much for your help thus far, and I may be able to work around this bit. But if you see anything obvious I’d be much obliged!

That message almost seems like the SSH tunnel is failing locally, on 127.0.0.1, and not on the VM side. Have you tried rebooting?

You can try to run that command manually too:

/usr/bin/ssh -V -N-S none -o Contro|Master=no -0
ExitOnForwardFailure=yes -o ConnectTimeout=10 -0
NumberOfPasswordPrompts=3 -o UserKnownHostsFile="/Users/
davidham/.ssh/known_hosts"-F/Users/davidham/.ssh/config-o
TCPKeepAlive=no -o ServerAlivelnterval=60 -o ServerAliveCountMax=1 -p 22
vagrant@192.168.56.5 -L 52665:localhost:3306