From a9061b9df5ec73436eed25ae8a4e53c7b4cb739a Mon Sep 17 00:00:00 2001 From: Edmundo Gonzalez <51725820+edgonmsft@users.noreply.github.com> Date: Mon, 18 Apr 2022 21:41:41 +0000 Subject: [PATCH 1/5] 1st --- proposals/devcontainer-features.md | 141 +++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 proposals/devcontainer-features.md diff --git a/proposals/devcontainer-features.md b/proposals/devcontainer-features.md new file mode 100644 index 00000000..4f9aea11 --- /dev/null +++ b/proposals/devcontainer-features.md @@ -0,0 +1,141 @@ +# Dev container features reference + +Dev container features provide a smooth path for customizing your container definitions. Features are self contained units of code meant to facilitate creation of custom images for application or development containers. + +From a practical point of view, features are folders that contain units of code with different entrypoints for different lifecycle events. + +Features can be defined by a `feature.json` file in the root folder of the feature. The file is optional for backwards compatibility but it is required for any new features being authored. + +Features are to be executed in sequence as defined in `devcontainer.json`. + +## Folder Structure + +A feature is a self contained entity in a folder. A feature release would be a tar file that contains all files part of the feature. + ++-- feature +| +-- feature.json +| +-- validate.sh (default) +| +-- aquire.sh (default) +| +-- install.sh (default) +| +-- (other files) + +In case `feature.json` does not include a reference for the lifecycle scripts the application will look for the default script names and will execute them if available. + +In case there is intent to create a set of features that share code, it is possible to create a feature collection in the following way: + +collectionFolder ++-- feature-collection.json ++-- common (or similar) +| +-- (library files) ++-- feature1 +| +-- feature.json +| +-- install.sh (or others) +| +-- (other files) ++-- feature2 +(etc) + +## feature.json properties + +the `feature.json` file defines information about the feature to be used by any tool that helps a user utilize them, and the way the feature will be executed. + +The properties of the file are as follows: + +| Property | Type | Description | +| :--- | :--- | :--- | +| id | string | Id of the feature/definition. The id should be unique in the context of the repository/published package where they exist. | +| name | string | Name of the feature/definition | +| description | string | Description of the feature/definition | +| version | string | Version of the feature. | +| metadata | any | Freeform data added by users for their own purposes. | +| keywords | array | List of keywords relevant to a user that would search for this definition/feature. | +| install.app | string | App to execute.ll (Optional, defaults to /bin/sh) | +| install.file | string | Parameters/script to execute. (Defaults to validate.sh) | +| options | object | Possible options to be passed as environment variables to the execution of the scripts | +| containerEnv | object | A set of name value pairs that sets or overrides environment variables. | +| privileged | boolean | If preveleged mode is required by the feature. | +| init | boolean | If its necesarry to run `init`. | +| capAdd | array | Additional capabilities needed by the feature. | +| securityOpt | array | Security options needed by the feature. | +| entrypoint | string | Set if the feature sets requires an entrypoint. | + +Options + +| Property | Type | Description | +| :--- | :--- | :--- | +| id | string | Id of the option | +| id.type | string | Type of the option | +| id.enum | string array | possible values | +| id.default | string | default value for the option | +| id.description | string | Description for the option | + +## feature-collection.json properties. + +A feature collection file is a compilation of the `feature.json` files for each individual feature. + +If the application finds a `feature-collection.json` file in the root of a downloaded tar file then it uses that file as to find the particular feature that will be executed. + +In addition to the list of features included, the file includes the following properties. + +| Property | Type | Description | +| :--- | :--- | :--- | +| name | string | Name of the collection | +| reference | string | Reference information of the repository and path where the code is stored. | +| version | string | Version of the code. | + +In most cases the `feature-collection.json` file can be generated automatically at the moment of creating a release. + +## devcontainer.json properties + +Features are referenced in `devcontainer.json` where the `features` tag consists of an array with the ordered list of features to be included in the container image. + +The properties are: +| Property | Type | Description | +| :--- | :--- | :--- | +| id | string | reference to the particular feature to be included. | +| options | object | Type of the option | + +The `id` is the main reference point for how to find and download a particular feature. `id` can be defined in any of the following ways: + +| Type | Description | +| :--- | :--- | +| feature | A simple name references a feature included with the application used to execute `devcontainer.json` | +| organization/repository/{feature or collectionl/feature}/@version | Reference to a particular release in a repository | +| https://<../URI/..>/devcontainer-features.tgz#{optional feature} | Direct reference to a file download. | +| ./{local-path} -or- ../{local-path} | A path relative to devcontainer.json where a feature or feature collection can be found. | + +## Authoring + +Features can be authored in a number of languages, the most straight forward being bash scripts. If a feature is authored in a different language information about it should be included in the metadata so that users can make an informed choice about it. + +Reference information about the application required to execute the feature should be included in `feature.json` in the metadata section. + +Applications should default to `/bin/sh` for features that do not include this information. + +If the feature is included in a folder as part of the repository that contains `devcontainer.json` no other steps are necessary. + +## Release + +A release is created when the objective is to have other users use a feature. + +A release consists of the following: + +1.- Tar file with all the included files for the feature or feature collection. +2.- A copy of the `feature.json` or `feature-collection.json` file that defines the contents of the tar file with additional information added to validate it: + +| Property | Type | Description | +| :--- | :--- | :--- | +| version | string | SemVer version of the release. | +| checksum | string | Checksum of the tar file. | + +## Execution + +The application that implements features should: + +- Features are executed in the order defined in devcontainer.json +- It should be possible to execute a feature multiple times with different parameters. +- Features are used to create an image that can be used to create a container or not. +- Parameters like `privileged`, ``init` are included if just 1 feature requires them. +- Parameters like `capAdd`, `securityOp` are concatenated. +- ContainerEnv is added before the feature is executed and persisted. + +TODO \ No newline at end of file From eed5b79165d7099cdb9fe2de0af3fa6429626176 Mon Sep 17 00:00:00 2001 From: Edmundo Gonzalez <51725820+edgonmsft@users.noreply.github.com> Date: Fri, 29 Apr 2022 16:15:17 +0000 Subject: [PATCH 2/5] Add urls. --- proposals/devcontainer-features.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/proposals/devcontainer-features.md b/proposals/devcontainer-features.md index 4f9aea11..0ceaa454 100644 --- a/proposals/devcontainer-features.md +++ b/proposals/devcontainer-features.md @@ -45,6 +45,8 @@ The properties of the file are as follows: | id | string | Id of the feature/definition. The id should be unique in the context of the repository/published package where they exist. | | name | string | Name of the feature/definition | | description | string | Description of the feature/definition | +| documentationURL | string | Url that targets the documentation of the feature. | +| licenseURL | string | Url that points to the license of the feature. | | version | string | Version of the feature. | | metadata | any | Freeform data added by users for their own purposes. | | keywords | array | List of keywords relevant to a user that would search for this definition/feature. | From 35382b07f8aaa245b151fbf861345af1543e47f2 Mon Sep 17 00:00:00 2001 From: Edmundo Gonzalez <51725820+edgonmsft@users.noreply.github.com> Date: Tue, 10 May 2022 22:40:13 +0000 Subject: [PATCH 3/5] Comments from PR. --- proposals/devcontainer-features.md | 31 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/proposals/devcontainer-features.md b/proposals/devcontainer-features.md index 0ceaa454..b099591f 100644 --- a/proposals/devcontainer-features.md +++ b/proposals/devcontainer-features.md @@ -4,7 +4,7 @@ Dev container features provide a smooth path for customizing your container defi From a practical point of view, features are folders that contain units of code with different entrypoints for different lifecycle events. -Features can be defined by a `feature.json` file in the root folder of the feature. The file is optional for backwards compatibility but it is required for any new features being authored. +Features can be defined by a `devcontainer-feature.json` file in the root folder of the feature. The file is optional for backwards compatibility but it is required for any new features being authored. Features are to be executed in sequence as defined in `devcontainer.json`. @@ -14,17 +14,16 @@ A feature is a self contained entity in a folder. A feature release would be a t +-- feature | +-- feature.json -| +-- validate.sh (default) | +-- aquire.sh (default) | +-- install.sh (default) | +-- (other files) -In case `feature.json` does not include a reference for the lifecycle scripts the application will look for the default script names and will execute them if available. +In case `devcontainer-feature.json` does not include a reference for the lifecycle scripts the application will look for the default script names and will execute them if available. In case there is intent to create a set of features that share code, it is possible to create a feature collection in the following way: collectionFolder -+-- feature-collection.json ++-- devcontainer.collection.json +-- common (or similar) | +-- (library files) +-- feature1 @@ -36,7 +35,7 @@ collectionFolder ## feature.json properties -the `feature.json` file defines information about the feature to be used by any tool that helps a user utilize them, and the way the feature will be executed. +the `devcontainer-feature.json` file defines information about the feature to be used by any tool that helps a user utilize them, and the way the feature will be executed. The properties of the file are as follows: @@ -50,8 +49,8 @@ The properties of the file are as follows: | version | string | Version of the feature. | | metadata | any | Freeform data added by users for their own purposes. | | keywords | array | List of keywords relevant to a user that would search for this definition/feature. | -| install.app | string | App to execute.ll (Optional, defaults to /bin/sh) | -| install.file | string | Parameters/script to execute. (Defaults to validate.sh) | +| install.app | string | App to execute.| +| install.file | string | Parameters/script to execute | | options | object | Possible options to be passed as environment variables to the execution of the scripts | | containerEnv | object | A set of name value pairs that sets or overrides environment variables. | | privileged | boolean | If preveleged mode is required by the feature. | @@ -70,11 +69,11 @@ Options | id.default | string | default value for the option | | id.description | string | Description for the option | -## feature-collection.json properties. +## devcontainer-collection.json properties. -A feature collection file is a compilation of the `feature.json` files for each individual feature. +A feature collection file is a compilation of the `devcontainer-feature.json` files for each individual feature. It inlines all the information in each `devcontainer-feature.json` for each feature. -If the application finds a `feature-collection.json` file in the root of a downloaded tar file then it uses that file as to find the particular feature that will be executed. +If the application finds a `devcontainer-collection.json` file in the root of a downloaded tar file then it uses that file as to find the particular feature that will be executed. In addition to the list of features included, the file includes the following properties. @@ -84,7 +83,7 @@ In addition to the list of features included, the file includes the following pr | reference | string | Reference information of the repository and path where the code is stored. | | version | string | Version of the code. | -In most cases the `feature-collection.json` file can be generated automatically at the moment of creating a release. +In most cases the `devcontainer-collection.json` file can be generated automatically at the moment of creating a release. ## devcontainer.json properties @@ -109,7 +108,7 @@ The `id` is the main reference point for how to find and download a particular f Features can be authored in a number of languages, the most straight forward being bash scripts. If a feature is authored in a different language information about it should be included in the metadata so that users can make an informed choice about it. -Reference information about the application required to execute the feature should be included in `feature.json` in the metadata section. +Reference information about the application required to execute the feature should be included in `devcontainer-feature.json` in the metadata section. Applications should default to `/bin/sh` for features that do not include this information. @@ -122,7 +121,7 @@ A release is created when the objective is to have other users use a feature. A release consists of the following: 1.- Tar file with all the included files for the feature or feature collection. -2.- A copy of the `feature.json` or `feature-collection.json` file that defines the contents of the tar file with additional information added to validate it: +2.- A copy of the `devcontainer-feature.json` or `devcontainer-collection.json` file that defines the contents of the tar file with additional information added to validate it: | Property | Type | Description | | :--- | :--- | :--- | @@ -138,6 +137,6 @@ The application that implements features should: - Features are used to create an image that can be used to create a container or not. - Parameters like `privileged`, ``init` are included if just 1 feature requires them. - Parameters like `capAdd`, `securityOp` are concatenated. -- ContainerEnv is added before the feature is executed and persisted. - -TODO \ No newline at end of file +- ContainerEnv is added before the feature is executed as `ENV` commands in the docker file. +- Features are added to an image in two passes. One for `aquire` scripts and another for `install` scripts. +- Each script executes as its own layer to aid in caching and rebuilding. \ No newline at end of file From 9498ed5cb2a74d52bfcfced9a9118190e8710abf Mon Sep 17 00:00:00 2001 From: Edmundo Gonzalez <51725820+edgonmsft@users.noreply.github.com> Date: Mon, 23 May 2022 16:48:28 +0000 Subject: [PATCH 4/5] PR changes --- proposals/devcontainer-features.md | 65 +++++++++++++++--------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/proposals/devcontainer-features.md b/proposals/devcontainer-features.md index b099591f..1ae610ea 100644 --- a/proposals/devcontainer-features.md +++ b/proposals/devcontainer-features.md @@ -13,7 +13,7 @@ Features are to be executed in sequence as defined in `devcontainer.json`. A feature is a self contained entity in a folder. A feature release would be a tar file that contains all files part of the feature. +-- feature -| +-- feature.json +| +-- devcontainer-feature.json | +-- aquire.sh (default) | +-- install.sh (default) | +-- (other files) @@ -23,96 +23,95 @@ In case `devcontainer-feature.json` does not include a reference for the lifecy In case there is intent to create a set of features that share code, it is possible to create a feature collection in the following way: collectionFolder -+-- devcontainer.collection.json ++-- devcontainer-collection.json +-- common (or similar) | +-- (library files) +-- feature1 -| +-- feature.json +| +-- devcontainer-feature.json | +-- install.sh (or others) | +-- (other files) +-- feature2 (etc) -## feature.json properties +## devcontainer-feature.json properties -the `devcontainer-feature.json` file defines information about the feature to be used by any tool that helps a user utilize them, and the way the feature will be executed. +the `devcontainer-feature.json` file defines information about the feature to be used by any supporting tools and the way the feature will be executed. The properties of the file are as follows: | Property | Type | Description | | :--- | :--- | :--- | -| id | string | Id of the feature/definition. The id should be unique in the context of the repository/published package where they exist. | -| name | string | Name of the feature/definition | -| description | string | Description of the feature/definition | -| documentationURL | string | Url that targets the documentation of the feature. | +| id | string | Id of the feature/definition. The id should be unique in the context of the repository/published package where the feature exists. | +| name | string | Name of the feature/definition. | +| description | string | Description of the feature/definition. | +| documentationURL | string | Url that points to the documentation of the feature. | | licenseURL | string | Url that points to the license of the feature. | | version | string | Version of the feature. | -| metadata | any | Freeform data added by users for their own purposes. | | keywords | array | List of keywords relevant to a user that would search for this definition/feature. | | install.app | string | App to execute.| -| install.file | string | Parameters/script to execute | +| install.file | string | Parameters/script to execute (defaults to install.sh).| | options | object | Possible options to be passed as environment variables to the execution of the scripts | | containerEnv | object | A set of name value pairs that sets or overrides environment variables. | -| privileged | boolean | If preveleged mode is required by the feature. | -| init | boolean | If its necesarry to run `init`. | +| privileged | boolean | If priveleged mode is required by the feature. | +| init | boolean | If it's necesarry to run `init`. | | capAdd | array | Additional capabilities needed by the feature. | | securityOpt | array | Security options needed by the feature. | -| entrypoint | string | Set if the feature sets requires an entrypoint. | +| entrypoint | string | Set if the feature requires an entrypoint. | Options | Property | Type | Description | | :--- | :--- | :--- | -| id | string | Id of the option | -| id.type | string | Type of the option | -| id.enum | string array | possible values | -| id.default | string | default value for the option | -| id.description | string | Description for the option | +| id | string | Id of the option. | +| id.type | string | Type of the option. | +| id.enum | string array | Possible values. | +| id.default | string | Default value for the option. | +| id.description | string | Description for the option. | -## devcontainer-collection.json properties. +## devcontainer-collection.json properties A feature collection file is a compilation of the `devcontainer-feature.json` files for each individual feature. It inlines all the information in each `devcontainer-feature.json` for each feature. -If the application finds a `devcontainer-collection.json` file in the root of a downloaded tar file then it uses that file as to find the particular feature that will be executed. +If the application finds a `devcontainer-collection.json` file in the root of a downloaded tar file, then it uses that file to find the particular feature that will be executed. In addition to the list of features included, the file includes the following properties. | Property | Type | Description | | :--- | :--- | :--- | -| name | string | Name of the collection | +| name | string | Name of the collection. | | reference | string | Reference information of the repository and path where the code is stored. | | version | string | Version of the code. | -In most cases the `devcontainer-collection.json` file can be generated automatically at the moment of creating a release. +In most cases, the `devcontainer-collection.json` file can be generated automatically at the moment of creating a release. ## devcontainer.json properties -Features are referenced in `devcontainer.json` where the `features` tag consists of an array with the ordered list of features to be included in the container image. +Features are referenced in `devcontainer.json` , where the `features` tag consists of an array with the ordered list of features to be included in the container image. The properties are: | Property | Type | Description | | :--- | :--- | :--- | -| id | string | reference to the particular feature to be included. | -| options | object | Type of the option | +| id | string | Reference to the particular feature to be included. | +| options | object | Type of the option .| The `id` is the main reference point for how to find and download a particular feature. `id` can be defined in any of the following ways: | Type | Description | | :--- | :--- | -| feature | A simple name references a feature included with the application used to execute `devcontainer.json` | -| organization/repository/{feature or collectionl/feature}/@version | Reference to a particular release in a repository | +| feature | A simple name referencing a feature; it's included with the application used to execute `devcontainer.json`.| +| organization/repository/{feature or collectionl/feature}/@version | Reference to a particular release in a repository. | | https://<../URI/..>/devcontainer-features.tgz#{optional feature} | Direct reference to a file download. | | ./{local-path} -or- ../{local-path} | A path relative to devcontainer.json where a feature or feature collection can be found. | ## Authoring -Features can be authored in a number of languages, the most straight forward being bash scripts. If a feature is authored in a different language information about it should be included in the metadata so that users can make an informed choice about it. +Features can be authored in a number of languages, the most straightforward being bash scripts. If a feature is authored in a different language information about it should be included in the metadata so that users can make an informed choice about it. Reference information about the application required to execute the feature should be included in `devcontainer-feature.json` in the metadata section. Applications should default to `/bin/sh` for features that do not include this information. -If the feature is included in a folder as part of the repository that contains `devcontainer.json` no other steps are necessary. +If the feature is included in a folder as part of the repository that contains `devcontainer.json`, no other steps are necessary. ## Release @@ -121,7 +120,7 @@ A release is created when the objective is to have other users use a feature. A release consists of the following: 1.- Tar file with all the included files for the feature or feature collection. -2.- A copy of the `devcontainer-feature.json` or `devcontainer-collection.json` file that defines the contents of the tar file with additional information added to validate it: +2.- A copy of the `devcontainer-feature.json` or `devcontainer-collection.json` file that defines the contents of the tar file, with additional information added to validate it. | Property | Type | Description | | :--- | :--- | :--- | @@ -130,12 +129,12 @@ A release consists of the following: ## Execution -The application that implements features should: +There are several things to keep in mind for an application that implements features: - Features are executed in the order defined in devcontainer.json - It should be possible to execute a feature multiple times with different parameters. - Features are used to create an image that can be used to create a container or not. -- Parameters like `privileged`, ``init` are included if just 1 feature requires them. +- Parameters like `privileged`, `init` are included if just 1 feature requires them. - Parameters like `capAdd`, `securityOp` are concatenated. - ContainerEnv is added before the feature is executed as `ENV` commands in the docker file. - Features are added to an image in two passes. One for `aquire` scripts and another for `install` scripts. From b0357e2c21ea77a263a570fe4ef78705fa10a00b Mon Sep 17 00:00:00 2001 From: Edmundo Gonzalez <51725820+edgonmsft@users.noreply.github.com> Date: Tue, 24 May 2022 16:46:31 +0000 Subject: [PATCH 5/5] Format fixes and comments from PR. --- proposals/devcontainer-features.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/proposals/devcontainer-features.md b/proposals/devcontainer-features.md index 1ae610ea..4320c120 100644 --- a/proposals/devcontainer-features.md +++ b/proposals/devcontainer-features.md @@ -12,26 +12,30 @@ Features are to be executed in sequence as defined in `devcontainer.json`. A feature is a self contained entity in a folder. A feature release would be a tar file that contains all files part of the feature. +``` +-- feature | +-- devcontainer-feature.json -| +-- aquire.sh (default) | +-- install.sh (default) | +-- (other files) +``` In case `devcontainer-feature.json` does not include a reference for the lifecycle scripts the application will look for the default script names and will execute them if available. In case there is intent to create a set of features that share code, it is possible to create a feature collection in the following way: +``` collectionFolder +-- devcontainer-collection.json +-- common (or similar) | +-- (library files) +-- feature1 | +-- devcontainer-feature.json -| +-- install.sh (or others) +| +-- install.sh | +-- (other files) +-- feature2 (etc) +``` + ## devcontainer-feature.json properties