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

Template upgrades #191

Open
drevell opened this issue Sep 6, 2023 · 0 comments
Open

Template upgrades #191

drevell opened this issue Sep 6, 2023 · 0 comments
Assignees
Labels
enhancement New feature or request

Comments

@drevell
Copy link
Contributor

drevell commented Sep 6, 2023

TL;DR

Allow old template output directories to be upgraded when a new template version is released.

Detailed design

(copying portions of an internal design doc)

When the user runs abc templates render to render a template, we'll save a "manifest" file into the destination directory. This file will contain the information needed to cleanly upgrade to a new version of the template in the future. It contains the template location, inputs, and hashes of all the output files. Example:


# Generated by the `abc templates` command, do not modify
template_location: 'github.com/abcxyz/abc.git//t/template_name'
template_hash: '24bda78ab23...'  # Recursive directory hash of template
inputs:
  gcp_project_id: '12345'
  service_account: 'foo@bar'
hashes:
  - file: 'main.tf'
    hash: 'sha256:1a2b3c4d5e6f...'
  - file: 'terraform.tf'
    hash: 'sha256:968ad987e87fb9...'

The manifest file will be named .abc/manifest_.lock.yaml. It will be placed in the template destination directory (which is usually the CWD where the user runs abc templates ...).

We'll add a new command:

templates upgrade [--force-overwrite] [--input=foo=bar] [--abort-on-conflict] [--location=github.com...] <manifest_filename>```

This will:

  1. download the latest version of the template
  2. if the template hasn't changed (its dirhash is the same), then exit with a message
  3. render the new template with the inputs that were saved in the manifest
  4. merge the new template output with the existing files in the filesystem. For each file in the new template output:
    a. If there's no existing file at that path, just save the new output file.
    a. If there is an existing file at that path, but it hasn't been customized (the hash matches the hash in the manifest), then overwrite it with the new file.
    a. If the file HAS been customized (its hash doesn't match the manifest), then call this a "conflict." Tell the user to manually merge the existing/old file with the new file. We'll put the old/existing file at $FILE.old and the new file at $FILE.new...
    a. If there was a file that was generated by the old version of the template that is not generated by the new version of the template: delete it if it wasn't customized, or tell the user to handle the conflict if it has been customized.

Flags:

  • --abort-on-conflict: if the upgrade can't apply cleanly due to customizations, abort rather than ask the user to resolve the conflict.
  • --force-overwrite: overwrite all output files, even if they have been customized by the user.
  • --input=foo=bar: two use cases:
    • provide any inputs that are required by the new template that weren't part of the original template
    • override any input values that were in the manifest, and use the new value instead when executing the new template.
  • --location=github.com/x/y.git?some/template?ref=v1.2.3: in the case where the local template is pinned to a specific ref (like ?ref=some_old_tag , then the user will need to include this flag to specify the new ref to upgrade to.


### Alternatives considered

_No response_

### Additional information

_No response_
@drevell drevell added the enhancement New feature or request label Sep 6, 2023
drevell added a commit that referenced this issue Sep 6, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.
drevell added a commit that referenced this issue Sep 6, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.
drevell added a commit that referenced this issue Sep 6, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.

Example manifest file:

```
api_version: 'cli.abcxyz.dev/v1alpha1'
template_location: 'github.com/abcxyz/abc.git//t/rest_server'
template_dirhash: 'h1:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03'
inputs:
  - name: 'my_input_1'
    value: 'my_value_1'
  - name: 'my_input_2'
    value: 'my_value_2'
output_hashes:
  - file: 'a/b/c.txt'
    hash: 'h1:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
  - file: 'd/e/f.txt'
    hash: 'h1:7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730'
```

Some of the field names have been changed since the design doc because
the old names seemed unclear.
drevell added a commit that referenced this issue Sep 6, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.

Example manifest file:

```
api_version: 'cli.abcxyz.dev/v1alpha1'
template_location: 'github.com/abcxyz/abc.git//t/rest_server'
template_dirhash: 'h1:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03'
inputs:
  - name: 'my_input_1'
    value: 'my_value_1'
  - name: 'my_input_2'
    value: 'my_value_2'
output_hashes:
  - file: 'a/b/c.txt'
    hash: 'h1:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
  - file: 'd/e/f.txt'
    hash: 'h1:7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730'
```

Some of the field names have been changed since the design doc because
the old names seemed unclear.
drevell added a commit that referenced this issue Sep 6, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.

Example manifest file:

```
api_version: 'cli.abcxyz.dev/v1alpha1'
template_location: 'github.com/abcxyz/abc.git//t/rest_server'
template_dirhash: 'h1:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03'
inputs:
  - name: 'my_input_1'
    value: 'my_value_1'
  - name: 'my_input_2'
    value: 'my_value_2'
output_hashes:
  - file: 'a/b/c.txt'
    hash: 'h1:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
  - file: 'd/e/f.txt'
    hash: 'h1:7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730'
```

Some of the field names have been changed since the design doc because
the old names seemed unclear.
drevell added a commit that referenced this issue Sep 6, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.

This PR contains custom unmarshaling but not custom marshaling. That
will be a separate PR.

Example manifest file:

```
api_version: 'cli.abcxyz.dev/v1alpha1'
template_location: 'github.com/abcxyz/abc.git//t/rest_server'
template_dirhash: 'h1:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03'
inputs:
  - name: 'my_input_1'
    value: 'my_value_1'
  - name: 'my_input_2'
    value: 'my_value_2'
output_hashes:
  - file: 'a/b/c.txt'
    hash: 'h1:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
  - file: 'd/e/f.txt'
    hash: 'h1:7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730'
```

Some of the field names have been changed since the design doc because
the old names seemed unclear.
drevell added a commit that referenced this issue Sep 7, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.

This PR contains custom unmarshaling but not custom marshaling. That
will be a separate PR.

Example manifest file:

```
api_version: 'cli.abcxyz.dev/v1alpha1'
template_location: 'github.com/abcxyz/abc.git//t/rest_server'
template_dirhash: 'h1:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03'
inputs:
  - name: 'my_input_1'
    value: 'my_value_1'
  - name: 'my_input_2'
    value: 'my_value_2'
output_hashes:
  - file: 'a/b/c.txt'
    hash: 'h1:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
  - file: 'd/e/f.txt'
    hash: 'h1:7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730'
```

Some of the field names have been changed since the design doc because
the old names seemed unclear.
drevell added a commit that referenced this issue Sep 7, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.

This PR contains custom unmarshaling but not custom marshaling. That
will be a separate PR.

Example manifest file:

```
api_version: 'cli.abcxyz.dev/v1alpha1'
template_location: 'github.com/abcxyz/abc.git//t/rest_server'
template_dirhash: 'h1:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03'
inputs:
  - name: 'my_input_1'
    value: 'my_value_1'
  - name: 'my_input_2'
    value: 'my_value_2'
output_hashes:
  - file: 'a/b/c.txt'
    hash: 'h1:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
  - file: 'd/e/f.txt'
    hash: 'h1:7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730'
```

Some of the field names have been changed since the design doc because
the old names seemed unclear.
drevell added a commit that referenced this issue Sep 7, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.

This PR contains custom unmarshaling but not custom marshaling. That
will be a separate PR.

Example manifest file:

```
api_version: 'cli.abcxyz.dev/v1alpha1'
template_location: 'github.com/abcxyz/abc.git//t/rest_server'
template_dirhash: 'h1:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03'
inputs:
  - name: 'my_input_1'
    value: 'my_value_1'
  - name: 'my_input_2'
    value: 'my_value_2'
output_hashes:
  - file: 'a/b/c.txt'
    hash: 'h1:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
  - file: 'd/e/f.txt'
    hash: 'h1:7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730'
```

Some of the field names have been changed since the design doc because
the old names seemed unclear.
drevell added a commit that referenced this issue Sep 7, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.

This PR contains custom unmarshaling but not custom marshaling. That
will be a separate PR.

Example manifest file:

```
api_version: 'cli.abcxyz.dev/v1alpha1'
template_location: 'github.com/abcxyz/abc.git//t/rest_server'
template_dirhash: 'h1:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03'
inputs:
  - name: 'my_input_1'
    value: 'my_value_1'
  - name: 'my_input_2'
    value: 'my_value_2'
output_hashes:
  - file: 'a/b/c.txt'
    hash: 'h1:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
  - file: 'd/e/f.txt'
    hash: 'h1:7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730'
```

Some of the field names have been changed since the design doc because
the old names seemed unclear.
drevell added a commit that referenced this issue Sep 8, 2023
Part of #191.

These structs will represent the contents of the new "manifest" file,
which contains all the information we'll need in the future to cleanly
upgrade a template output.

This PR contains custom unmarshaling but not custom marshaling. That
will be a separate PR.

Example manifest file:

```
api_version: 'cli.abcxyz.dev/v1alpha1'
template_location: 'github.com/abcxyz/abc.git//t/rest_server'
template_dirhash: 'h1:5891b5b522d5df086d0ff0b110fbd9d21bb4fc7163af34d08286a2e846f6be03'
inputs:
  - name: 'my_input_1'
    value: 'my_value_1'
  - name: 'my_input_2'
    value: 'my_value_2'
output_hashes:
  - file: 'a/b/c.txt'
    hash: 'h1:b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c'
  - file: 'd/e/f.txt'
    hash: 'h1:7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730'
```

Some of the field names have been changed since the design doc because
the old names seemed unclear.
@drevell drevell self-assigned this Jan 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

No branches or pull requests

1 participant