Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
329 changes: 328 additions & 1 deletion .github/copilot-instructions.md

Large diffs are not rendered by default.

136 changes: 136 additions & 0 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ jobs:
run: bundle exec mixlib-install download chef
- name: Chef Licensed download Test
run: bundle exec mixlib-install download chef -L free-79df705d-b685-419a-8b68-88401f74ff72-3999
- name: Chef ICE download Test
if: runner.os != 'macOS'
run: bundle exec mixlib-install download chef-ice -L free-79df705d-b685-419a-8b68-88401f74ff72-3999
test-install-command:
runs-on: ${{ matrix.os }}
strategy:
Expand Down Expand Up @@ -353,3 +356,136 @@ jobs:
"@ | Out-File -FilePath test_with_license.rb -Encoding utf8
- name: Test ScriptGenerator with license_id
run: bundle exec ruby test_with_license.rb
test-install-command-chef-ice:
name: Test chef-ice install command generation and execution
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- name: Enable long paths on Windows
if: runner.os == 'Windows'
run: |
# Enable Windows long paths
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force -ErrorAction SilentlyContinue
# Enable Git long paths
git config --global core.longpaths true
- name: Checkout code
uses: actions/checkout@v6
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.4
bundler-cache: true
- name: Generate install command script (Linux/macOS)
if: runner.os != 'Windows'
run: |
# Generate the install command using Ruby API
bundle exec ruby -e "
require 'bundler/setup'
require 'mixlib/install'
installer = Mixlib::Install.new(
channel: :stable,
product_name: 'chef-ice',
license_id: 'free-79df705d-b685-419a-8b68-88401f74ff72-3999'
)
puts installer.install_command
" > install_cmd.sh
cat install_cmd.sh
chmod +x install_cmd.sh
- name: Run install command script (Linux/macOS)
if: runner.os != 'Windows'
run: |
# Run the install command with sudo
sudo bash install_cmd.sh
# Verify chef-client was installed (chef-ice installs chef-infra-client)
which chef-client
chef-client --version
- name: Generate install command script (Windows)
if: runner.os == 'Windows'
run: |
# Generate the install command using Ruby API (one-liner for PowerShell)
bundle exec ruby -e "require 'bundler/setup'; require 'mixlib/install'; installer = Mixlib::Install.new(channel: :stable, product_name: 'chef-ice', license_id: 'free-79df705d-b685-419a-8b68-88401f74ff72-3999', shell_type: :ps1); File.write('install_cmd.ps1', installer.install_command)"
Get-Content install_cmd.ps1
- name: Run install command script (Windows)
if: runner.os == 'Windows'
run: |
# Run the install command
.\install_cmd.ps1
# Refresh PATH from registry to pick up newly installed chef-client
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
# Verify chef-client was installed
Get-Command chef-client
chef-client --version
test-install-sh-chef-ice:
name: Test chef-ice install.sh generation and execution
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
steps:
- name: Checkout code
uses: actions/checkout@v6

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.4
bundler-cache: true
- name: Generate install.sh script for chef-ice
run: |
bundle exec ruby -e "
require 'bundler/setup'
require 'mixlib/install'
installer = Mixlib::Install.new(
channel: :stable,
product_name: 'chef-ice',
license_id: 'free-79df705d-b685-419a-8b68-88401f74ff72-3999'
)
File.write('install.sh', installer.install_command)
"
chmod +x install.sh
echo "Generated install.sh:"
cat install.sh
- name: Run install.sh script
run: |
sudo ./install.sh

# Verify chef-client was installed (chef-ice installs chef-infra-client)
which chef-client
chef-client --version
test-install-ps1-chef-ice:
name: Test chef-ice install.ps1 generation and execution
runs-on: windows-latest
steps:
- name: Enable long paths on Windows
run: |
# Enable Windows long paths
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force -ErrorAction SilentlyContinue
# Enable Git long paths
git config --global core.longpaths true
- name: Checkout code
uses: actions/checkout@v6

- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.4
bundler-cache: true
- name: Generate install.ps1 script for chef-ice
run: |
bundle exec ruby -e "require 'bundler/setup'; require 'mixlib/install'; installer = Mixlib::Install.new(channel: :stable, product_name: 'chef-ice', license_id: 'free-79df705d-b685-419a-8b68-88401f74ff72-3999', shell_type: :ps1); File.write('install.ps1', installer.install_command)"
Write-Host "Generated install.ps1:"
Get-Content install.ps1
- name: Run install.ps1 script
run: |
# Import the module and call the install function
. .\install.ps1
install
# Refresh PATH from registry to pick up newly installed chef-client
$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
# Verify chef-client was installed
Get-Command chef-client
chef-client --version
104 changes: 104 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,110 @@ Then set an environment variable to load them like this on linux:

Calls to mixlib-install now allow to target your new product, assuming the api_url match pacakges api for `/<channel>/<product>/versions` and `/<channel>/<product>/<version>/artifacts` endpoints.

## Licensed API Usage (Commercial and Trial)

Mixlib::Install supports both commercial and trial API endpoints for licensed Chef products. These APIs require a valid license ID and have specific restrictions.

### Trial API

The trial API is designed for evaluation purposes and has the following restrictions:

- **Endpoint**: `https://chefdownload-trial.chef.io`
- **License ID Format**: Must start with `free-` or `trial-`
- **Channel Restriction**: Only `stable` channel is supported
- **Version Restriction**: Only `latest` version is supported

When using a trial license ID, mixlib-install will **automatically** default to `stable` channel and `latest` version, displaying warnings if other values are provided:

```ruby
options = {
product_name: 'chef',
channel: :current, # Will be changed to :stable with warning
product_version: '18.5.0', # Will be changed to :latest with warning
license_id: 'free-trial-abc-123'
}

mi = Mixlib::Install.new(options)
# WARNING: Trial API only supports 'stable' channel. Changing from 'current' to 'stable'.
# WARNING: Trial API only supports 'latest' version. Changing from '18.5.0' to 'latest'.

mi.options.channel # => :stable
mi.options.product_version # => :latest
```

### Commercial API

The commercial API provides full access to all channels and versions:

- **Endpoint**: `https://chefdownload-commercial.chef.io`
- **License ID Format**: Any valid commercial license ID (not starting with `free-` or `trial-`)
- **Channel Restriction**: None - all channels supported (`stable`, `current`, `unstable`)
- **Version Restriction**: None - all versions supported

```ruby
options = {
product_name: 'chef',
channel: :current,
product_version: '18.5.0',
license_id: 'commercial-license-key-123'
}

mi = Mixlib::Install.new(options)
# No warnings or defaults applied
mi.options.channel # => :current
mi.options.product_version # => '18.5.0'
```

### Chef-ICE Product

The `chef-ice` product requires additional parameters (`m`, `p`, `pm`) and works with both commercial and trial APIs:

```ruby
options = {
product_name: 'chef-ice',
channel: :stable,
product_version: :latest,
platform: 'ubuntu',
platform_version: '20.04',
architecture: 'x86_64',
license_id: 'free-trial-abc-123' # Trial API
}

artifact = Mixlib::Install.new(options).artifact_info
artifact.url
# => "https://chefdownload-trial.chef.io/stable/chef-ice/download?v=19.1.151&license_id=free-trial-abc-123&m=x86_64&p=linux&pm=deb"
```

### Static Script Methods

The static methods `Mixlib::Install.install_sh()` and `Mixlib::Install.install_ps1()` also enforce trial API defaults:

```ruby
# Trial API defaults applied to generated script
script = Mixlib::Install.install_sh(
license_id: 'free-trial-xyz',
channel: :current, # Will be changed to :stable with warning
version: '18.0.0' # Will be changed to :latest with warning
)
# WARNING: Trial API only supports 'stable' channel. Changing from 'current' to 'stable'.
# WARNING: Trial API only supports 'latest' version. Changing from '18.0.0' to 'latest'.
```

### License ID Detection

You can check if a license ID is for trial or commercial API:

```ruby
require 'mixlib/install/dist'

Mixlib::Install::Dist.trial_license?('free-trial-123') # => true
Mixlib::Install::Dist.trial_license?('trial-abc-456') # => true
Mixlib::Install::Dist.trial_license?('commercial-xyz') # => false

Mixlib::Install::Dist.commercial_license?('commercial-xyz') # => true
Mixlib::Install::Dist.commercial_license?('free-trial-123') # => false
```

## Development

VCR is a tool that helps cache and replay http responses. When these responses change or when you add more tests you might need to update cached responses. Check out [spec_helper.rb](https://github.com/chef/mixlib-install/blob/master/spec/spec_helper.rb) for instructions on how to do this.
Expand Down
Loading
Loading