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

Multiline Environment= declarations aren't properly parsed #183

Open
piotrp opened this issue Oct 21, 2024 · 1 comment
Open

Multiline Environment= declarations aren't properly parsed #183

piotrp opened this issue Oct 21, 2024 · 1 comment

Comments

@piotrp
Copy link

piotrp commented Oct 21, 2024

I am trying to use systemctl3.py with services that need long environment variables with newlines, and I noticed that newlines aren't supported.

Example from my service:

Environment="FLINK_ENV_JAVA_OPTS_JM=-Dcom.sun.management.jmxremote \
              -Dcom.sun.management.jmxremote.port=9951 \
              -Dcom.sun.management.jmxremote.rmi.port=9951 \
              -Dcom.sun.management.jmxremote.authenticate=false \
              -Dcom.sun.management.jmxremote.ssl=false \
              -Dcom.sun.management.jmxremote.local.only=false \
              -Djava.rmi.server.hostname=172.20.128.132"

A shorter standalone test case:

[Unit]
Description=Env test

[Service]
Environment="MULTILINE=line1 \
  line2"
ExecStart=/usr/bin/env

[Install]
WantedBy=default.target

Output logged after starting this service:

...
OLDPWD=/root
MULTILINE=line1
MAINPID=
...

A quick test with additional logging in read_env_part (logg.info("env part: %s", env_part)) shows that the value is read correctly, and the only issue is with the way that read_env_part interprets this data:

$ systemctl --user -vv start envtest
INFO:systemctl:EXEC BEGIN /usr/bin/systemctl start envtest --user
INFO:systemctl:env part: "MULTILINE=line1 \
  line2"

INFO:systemctl:simple start '/usr/bin/env'
@piotrp
Copy link
Author

piotrp commented Oct 21, 2024

I did a quick test and looks like this read_env_part implementation works better:

            for found in re.finditer(r'\s*("[\w_]+=[^"]*"|[\w_]+=\S*)', env_part.strip()):
                part = found.group(1)
                if part.startswith('"'):
                    part = part[1:-1]
                name, value = part.split("=", 1)
                yield name, value.replace("\\\n", "")

Replacing at the end is needed because \ at the end of line is meant to remove the newline character and join lines.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant