bitwalker / distillery

Simplify deployments in Elixir with OTP releases!
MIT License
2.97k stars 400 forks source link

Is SYS_CONFIG_PATH code correct? #398

Closed fxn closed 6 years ago

fxn commented 6 years ago

This is perhaps more a question than an issue.

I was reading today code related to SYS_CONFIG_PATH and saw:

if [ -z "$SYS_CONFIG_PATH" ]; then
    if [ -f "$RELEASE_CONFIG_DIR/sys.config" ]; then
        export SRC_SYS_CONFIG_PATH="$RELEASE_CONFIG_DIR/sys.config"
    else
        export SRC_SYS_CONFIG_PATH="$REL_DIR/sys.config"
    fi
else
    export SRC_SYS_CONFIG_PATH="$SYS_CONFIG_PATH"
fi
if [ "$SRC_SYS_CONFIG_PATH" != "$RELEASE_MUTABLE_DIR/sys.config" ]; then
    (echo "%% Generated - edit/create $RELEASE_CONFIG_DIR/sys.config instead."; \
    cat  "$SRC_SYS_CONFIG_PATH")                              \
        > "$RELEASE_MUTABLE_DIR/sys.config"
    export DEST_SYS_CONFIG_PATH="$RELEASE_MUTABLE_DIR"/sys.config
fi
if [ ! -z "$REPLACE_OS_VARS" ]; then
    _replace_os_vars "$DEST_SYS_CONFIG_PATH"
fi
export SYS_CONFIG_PATH="${SYS_CONFIG_PATH:-$DEST_SYS_CONFIG_PATH}"

in config.sh.

If SYS_CONFIG_PATH is set by the user, a bunch of things are done, and then the last assignment is:

export SYS_CONFIG_PATH="${SYS_CONFIG_PATH:-$DEST_SYS_CONFIG_PATH}"

That leaves SYS_CONFIG_PATH with its original value. I would expect -config to get the user's explictly configured config file, so that :init.get_argument(:config) matches. In principle the assignment seems fine to me. But then, why the else clause and the rest of the code?

bitwalker commented 6 years ago

Yes, this is correct, we only want to set it to $DEST_SYS_CONFIG_PATH if it wasn't explicitly set by the user.

fxn commented 6 years ago

Let me reword the question.

Let's suppose the user has set SYS_CONFIG_PATH.

If the value is different than $RELEASE_MUTABLE_DIR/sys.config, then the file is copied to $RELEASE_MUTABLE_DIR/sys.config and variables replaced there if needed.

Isn't that work discarded then by

export SYS_CONFIG_PATH="${SYS_CONFIG_PATH:-$DEST_SYS_CONFIG_PATH}"

? The scripts later pass SYS_CONFIG_PATH as -config right?

bitwalker commented 6 years ago

We don't ever want to override an explicit SYS_CONFIG_PATH - yes we will regenerate RELEASE_MUTABLE_DIR/sys.config if they are different, but that is simply because we set SRC_SYS_CONFIG_PATH so that we don't have to check if it is set or not - but we aren't going to use the generated config in this case, we will just use SYS_CONFIG_PATH. The generated config is used in cases where SYS_CONFIG_PATH is not set, and we are instead inferring the sys.config path based on either RELEASE_CONFIG_DIR (if that is set) or from the sys.config included in the release itself (i.e. REL_DIR/sys.config. In which case we generate a config from the source file, and reference the generated config rather than the source.

If anything should be changed, it should probably be to change:

if [ "$SRC_SYS_CONFIG_PATH" != "$RELEASE_MUTABLE_DIR/sys.config" ]; then

to:

if [ ! -z "$SRC_SYS_CONFIG_PATH" ] && [ "$SRC_SYS_CONFIG_PATH" != "$RELEASE_MUTABLE_DIR/sys.config" ]; then

and then remove the line which sets SRC_SYS_CONFIG_PATH when SYS_CONFIG_PATH is set. I haven't done this because it isn't actually necessary, but would be a reasonable clean up task to do.

fxn commented 6 years ago

I believe the whole code could be simplified to this:

if [ -z "$SYS_CONFIG_PATH" ]; then
    export SYS_CONFIG_PATH="$RELEASE_MUTABLE_DIR/sys.config"
    if [ -f "$RELEASE_CONFIG_DIR/sys.config" ]; then
        export SRC_SYS_CONFIG_PATH="$RELEASE_CONFIG_DIR/sys.config"
    else
        export SRC_SYS_CONFIG_PATH="$REL_DIR/sys.config"
    fi
    (echo "%% Generated - edit/create $RELEASE_CONFIG_DIR/sys.config instead."; \
    cat "$SRC_SYS_CONFIG_PATH") > "$SYS_CONFIG_PATH"
    if [ ! -z "$REPLACE_OS_VARS" ]; then
        _replace_os_vars "$SYS_CONFIG_PATH"
    fi
fi

Because:

Perhaps I overlooked something though... what do you think?

bitwalker commented 6 years ago

I think there are a few things you aren't factoring in, and it is definitely not your fault, but is one of the reasons why this code is so awfully complex:

This aspect of the management scripts is the single most complicated part of the whole thing, the rest of it is a cakewalk in comparison, because of all the implicit behavior accounted for. I really need to comment the code more heavily than it is today. In any case, I thank you for questioning what is there, both because you found a bug, but also because it forces me to double check everything :)

fxn commented 6 years ago

Fantastic @bitwalker! Thank you very much for the detailed explanation ❤️.