File opensuse-migration-tool-20250521.ab8700a.obscpio of Package opensuse-migration-tool

07070100000000000081A4000000000000000000000001682DAB21000023C2000000000000000000000000000000000000003100000000opensuse-migration-tool-20250521.ab8700a/LICENSEApache License
Version 2.0, January 2004
http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.

"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.

"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.

"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.

"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.

"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.

"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).

"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.

"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."

"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:

    You must give any other recipients of the Work or Derivative Works a copy of this License; and
    You must cause any modified files to carry prominent notices stating that You changed the files; and
    You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
    If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.

You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

07070100000001000081A4000000000000000000000001682DAB21000014B9000000000000000000000000000000000000003300000000opensuse-migration-tool-20250521.ab8700a/README.md# openSUSE migration tool

The tool was created during [Hackweek 24](https://hackweek.opensuse.org/24/projects/new-migration-tool-for-leap).

The goal is to simplify upgrades and cross-distribution migrations within openSUSE distributions.

It also supports migration from openSUSE Leap to SUSE Linux Enterprise.

**The tool is still experimental and is not expected to be used in production until we have a proper test suite.**

![image](https://github.com/user-attachments/assets/5eb2e5ee-ce07-4319-a477-6e66b27f339b)


The tool gets information about point releases from [get.opensuse.org API](https://get.opensuse.org/api/v0/distributions.json) 
and also utilizes [openSUSE-repos](https://github.com/openSUSE/openSUSE-repos) for a cross distribution migration.
Installing openSUSE-repos from the target repo of an upgrade or migration takes away any manual tinkering of distribution repositories.

**Intended supported scenarios**
```
Leap -> Leap n+1, Leap -> SLES, Leap -> Tumbleweed, Leap -> Slowroll
Leap Micro -> Leap Micro n+1, Leap Micro -> MicroOS
Slowroll -> Tumbleweed
Tumbleweed -> Slowroll
```

**Known unsupported scenarios**

Migration from Tumbleweed (rolling) to any point release is not possible as it's effectively a downgrade.
Migration from non-immutable to immutable is generally unsupported and not recommended. 
So no option for Tumbleweed -> MicroOS either.
For such unsupported cases please do a clean install.




## License
This project uses the [Apache-2.0](http://www.apache.org/licenses/LICENSE-2.0) license.

## Testing

Please always run the tool first with --dry-run to get an overall idea of what the tool would do to your system.
I highly recommend testing the tool in a virtual machine or container via e.g. distrobox.

### Execution on a regular system such as Leap, Tumbleweed, Slowroll

```
$ sudo zypper in opensuse-migration-tool
$ opensuse-migration-tool --dry-run
$ sudo opensuse-migration-tool
$ reboot
```

### Execution on Immutable systems such as Leap Micro

```
$ sudo transactional-update shell
# Inside the shell
$ sudo zypper in opensuse-migration-tool
$ opensuse-migration-tool --dry-run
$ sudo opensuse-migration-tool
$ exit && reboot # into new snapshot
```

### Upgrading to pre-releases such as Alpha, Beta

By default the tool with **not show up** Alpha, Beta, RC releases of point releases as viable targets for upgrade/migration.
E.g. Leap Micro 6.1 Beta or Leap 16.9 Alpha.

This is on purpose. We want to ensure that nobody accidentally upgrades their system to e.g. Alpha version of an upcoming release.

The --pre-release argument does the trick, then we'll fetch information from [get.opensuse.org API](https://get.opensuse.org/api/v0/distributions.json) about all available releases which are not EOL.
Default behavior is to fetch only releases with state "Stable" which means released/supported.


```
./opensuse-migration-tool --pre-release --dry-run
sudo ./opensuse-migration-tool --pre-release

```

### Alternatively with git/distrobox (recommended for development)

Leap Micro migration can be easily developed/tested on a toolbox image. 
Just be aware that the toolbox container won't be immutable inside, so no need for transactional-update here.

Please be aware that in such a container environment there could be an issue with updating bind-mounted files such as [/etc/hostname](https://bugzilla.opensuse.org/show_bug.cgi?id=1233982).
```
$ git clone https://github.com/openSUSE/opensuse-migration-tool.git
$ cd opensuse-migration-tool
$ distrobox create --image registry.opensuse.org/opensuse/leap-micro/6.0/toolbox --name micro60
$ distrobox enter micro60
$ zypper in bc jq curl dialog sed gawk
$ ./opensuse-migration-tool --dry-run
$ sudo ./opensuse-migration-tool
```

```
$ git clone https://github.com/openSUSE/opensuse-migration-tool.git
$ cd opensuse-migration-tool
$ distrobox create --image opensuse/leap:15.5 --name leap155
$ distrobox enter leap155
$ sudo zypper in bc jq curl dialog sed gawk
$ ./opensuse-migration-tool --dry-run
$ sudo ./opensuse-migration-tool
```

## Documentation for a manual migration

These are wiki that describe the manual upgrade process with zypper dup

https://en.opensuse.org/SDB:System_upgrade

https://en.opensuse.org/SDB:How_to_migrate_to_SLE

https://en.opensuse.org/SDB:System_upgrade_to_LeapMicro_6.0

### Packaging
```
$ osc bco Base:System opensuse-migration-tool # fork Package from Base:System
$ cd Base:System/opensuse-migration-tool
$ osc service runall
$ osc addremove
$ vim *.changes # review changelog, deduplicate lines from git history etc.
$ osc build # ensure that changes build locally
$ osc commit
$ osc sr # submit changes to the Base:System
```
**Maintainer typically forwards submission from devel project to openSUSE:Factory on accept.**

If this is not the case you can submit it manually.

```
$ osc sr Base:System opensuse-migration-tool openSUSE:Factory
```

Aside from Factory we want to ensure that supported Leap Micro and Leap releases get the update too.
**Once changes are accepted in openUSSE:Factory do following.**

```
$ osc sr openSUSE:Factory opensuse-migration-tool openSUSE:Leap:Micro:6.1
$ osc sr openSUSE:Factory opensuse-migration-tool openSUSE:Leap:16.0
$ osc sr openSUSE:Factory opensuse-migration-tool openSUSE:Leap:15.6:Update
```
07070100000002000081A4000000000000000000000001682DAB2100000B95000000000000000000000000000000000000003300000000opensuse-migration-tool-20250521.ab8700a/SLES.prod<?xml version="1.0" encoding="UTF-8"?>
<product schemeversion="0">
  <vendor>SUSE</vendor>
  <name>SLES</name>
  <version>15.6</version>
  <baseversion>15</baseversion>
  <patchlevel>6</patchlevel>
  <release>0</release>
  <endoflife></endoflife>
  <arch>x86_64</arch>
  <cpeid>cpe:/o:suse:sles:15:sp6</cpeid>
  <productline>sles</productline>
  <codestream>
    <name>SUSE Linux Enterprise Server 15</name>
    <endoflife>2031-07-31</endoflife>
  </codestream>
  <register>
      <target>sle-15-x86_64</target>
  </register>
  <repositories>
      <repository type="update" repoid="obsrepository://build.suse.de/SUSE:Updates:SLE-Product-SLES:15-SP6:x86_64/update" />
      <repository type="update" repoid="obsrepository://build.suse.de/SUSE:Updates:SLE-Product-SLES:15-SP6:x86_64/update_debug" />
      <repository type="update" repoid="obsrepository://build.suse.de/SUSE:Updates:SLE-INSTALLER:15-SP6:x86_64/update" />
      <repository type="pool" repoid="obsproduct://build.suse.de/SUSE:Products:SLE-Product-SLES:15-SP6:x86_64/SLES/15.6/x86_64" />
  </repositories>
  <summary>SUSE Linux Enterprise Server 15 SP6</summary>
  <shortsummary>SLES15-SP6</shortsummary>
  <description>SUSE Linux Enterprise offers a comprehensive
        suite of products built on a single code base.
        The platform addresses business needs from
        the smallest thin-client devices to the world's
        most powerful high-performance computing
        and mainframe servers. SUSE Linux Enterprise
        offers common management tools and technology
        certifications across the platform, and
        each product is enterprise-class.</description>
  <linguas>
    <language>cs</language>
    <language>da</language>
    <language>de</language>
    <language>en</language>
    <language>en_GB</language>
    <language>en_US</language>
    <language>es</language>
    <language>fi</language>
    <language>fr</language>
    <language>hu</language>
    <language>it</language>
    <language>ja</language>
    <language>nb</language>
    <language>nl</language>
    <language>pl</language>
    <language>pt</language>
    <language>pt_BR</language>
    <language>ru</language>
    <language>sv</language>
    <language>zh</language>
    <language>zh_CN</language>
    <language>zh_TW</language>
  </linguas>
  <urls>
    <url name="releasenotes">https://www.suse.com/releasenotes/x86_64/SUSE-SLES/15-SP6/release-notes-sles.rpm</url>
  </urls>
  <buildconfig>
    <producttheme>SLES</producttheme>
  </buildconfig>
  <installconfig>
    <defaultlang>en_US</defaultlang>
    <releasepackage name="sles-release" flag="EQ" version="15.6" release="150600.64.3.1"/>
    <distribution>SUSE_SLE</distribution>
  </installconfig>
  <runtimeconfig/>
  <productdependency relationship="provides" name="SUSE_SLE" baseversion="15" patchlevel="6" flag="EQ"/>
  <productdependency relationship="provides" name="SUSE_SLE-SP6" baseversion="15" patchlevel="6" flag="EQ"/>
</product>

07070100000003000081A4000000000000000000000001682DAB2100000B43000000000000000000000000000000000000003200000000opensuse-migration-tool-20250521.ab8700a/dialogrc#
# Run-time configuration file for dialog
#
# Automatically generated by "dialog --create-rc <file>"
#
#
# Types of values:
#
# Number     -  <number>
# String     -  "string"
# Boolean    -  <ON|OFF>
# Attribute  -  (foreground,background,highlight?)

# Set aspect-ration.
aspect = 0

# Set separator (for multiple widgets output).
separate_widget = ""

# Set tab-length (for textbox tab-conversion).
tab_len = 8

# Make tab-traversal for checklist, etc., include the list.
visit_items = OFF

# Shadow dialog boxes? This also turns on color.
use_shadow = ON

# Turn color support ON or OFF
use_colors = ON

# Screen color
screen_color = (GREEN,GREEN,ON)

# Shadow color
shadow_color = (BLACK,BLACK,ON)

# Dialog box color
dialog_color = (BLACK,WHITE,OFF)

# Dialog box title color
title_color = (BLACK,WHITE,ON)

# Dialog box border color
border_color = (WHITE,WHITE,ON)

# Active button color
button_active_color = (WHITE,GREEN,ON)

# Inactive button color
button_inactive_color = dialog_color

# Active button key color
button_key_active_color = button_active_color

# Inactive button key color
button_key_inactive_color = (BLACK,WHITE,OFF)

# Active button label color
button_label_active_color = (WHITE,GREEN,ON)

# Inactive button label color
button_label_inactive_color = (BLACK,WHITE,ON)

# Input box color
inputbox_color = dialog_color

# Input box border color
inputbox_border_color = dialog_color

# Search box color
searchbox_color = dialog_color

# Search box title color
searchbox_title_color = title_color

# Search box border color
searchbox_border_color = border_color

# File position indicator color
position_indicator_color = title_color

# Menu box color
menubox_color = dialog_color

# Menu box border color
menubox_border_color = border_color

# Item color
item_color = dialog_color

# Selected item color
item_selected_color = button_active_color

# Tag color
tag_color = title_color

# Selected tag color
tag_selected_color = button_label_active_color

# Tag key color
tag_key_color = button_key_inactive_color

# Selected tag key color
tag_key_selected_color = (WHITE,GREEN,ON)

# Check box color
check_color = dialog_color

# Selected check box color
check_selected_color = button_active_color

# Up arrow color
uarrow_color = (GREEN,WHITE,ON)

# Down arrow color
darrow_color = uarrow_color

# Item help-text color
itemhelp_color = (WHITE,BLACK,OFF)

# Active form text color
form_active_text_color = button_active_color

# Form text color
form_text_color = (WHITE,CYAN,ON)

# Readonly form item color
form_item_readonly_color = (CYAN,WHITE,ON)

# Dialog box gauge color
gauge_color = (GREEN,WHITE,ON)

# Dialog box border2 color
border2_color = dialog_color

# Input box border2 color
inputbox_border2_color = dialog_color

# Search box border2 color
searchbox_border2_color = dialog_color

# Menu box border2 color
menubox_border2_color = dialog_color
07070100000004000081ED000000000000000000000001682DAB2100005145000000000000000000000000000000000000004100000000opensuse-migration-tool-20250521.ab8700a/opensuse-migration-tool#!/bin/bash
# openSUSE migration and upgrade tool utilizes get.opensuse.org product API and openSUSE-repos
# for a cross-distro migration and upgrade to a new versions of point releases.
#
# Copyright 2024 Marcela Maslanova, SUSE LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# For accessing files from git checkout
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )

# Set nice green instead of default blue

if [[ $COLORTERM =~ ^(truecolor|24bit)$ ]]; then
	DIALOGRC="/usr/share/opensuse-migration-tool/dialogrc"
	if [ -f "$SCRIPT_DIR/dialogrc" ]; then
		DIALOGRC="$SCRIPT_DIR/dialogrc"
	fi
	export DIALOGRC
fi

# Ensure required tools are installed
REQUIRED_TOOLS=("bc" "jq" "curl" "dialog" "sed" "gawk")
for tool in "${REQUIRED_TOOLS[@]}"; do
    if ! command -v "$tool" &>/dev/null; then
        echo "$tool is required but not installed."
        echo "Please run: sudo zypper in ${REQUIRED_TOOLS[*]}"
        exit 1
    fi
done
# Ensure Bash version is 4.0+
if ((BASH_VERSINFO[0] < 4)); then
    echo "This script requires Bash 4.0 or higher." >&2
    exit 1
fi
# Ensure /etc/os-release exists
if [[ ! -f /etc/os-release ]]; then
    echo "File /etc/os-release not found." >&2
    exit 2
fi
# Source OS release info
source /etc/os-release
ARCH=$(uname -i) # x86_64 XXX: check for other arches

# Fetch distribution data from API
API_URL="https://get.opensuse.org/api/v0/distributions.json"
API_DATA=$(curl -s "$API_URL")
if [ $? != 0 ]; then
    echo "Network error: Unable to fetch release data from https://get.opensuse.org/api/v0/distributions.json"
    echo "Ensure that you have working network connectivity and get.opensuse.org is accessible."
    exit 3
fi
DRYRUN=""
PRERELEASE=""
TMP_REPO_NAME="tmp-migration-tool-repo" # tmp repo to get sles-release or openSUSE-repos-*
# Initialize MIGRATION_OPTIONS as an empty associative array
declare -A MIGRATION_OPTIONS=()
CURRENT_INDEX=1
# Parse command-line arguments
function print_help() {
    echo "Usage: opensuse-migration-tool [--pre-release] [--dry-run] [--help]"
    echo "  --pre-release  Include pre-release versions in the migration options."
    echo "  --dry-run      Show commands without executing them."
    echo "  --help         Show this help message and exit."
    exit 0
}
while [[ $# -gt 0 ]]; do
    case $1 in
        --pre-release) PRERELEASE="YES"; shift ;;
        --dry-run) DRYRUN="echo Would execute: "; shift ;;
        --help) print_help ;;
        *) echo "Unknown option: $1"; exit 1 ;;
    esac
done
# Populate migration options
function fetch_versions() {
    local filter="$1"
    local key="$2"
    jq -r ".${key}[] | select(${filter}) | .version" <<<"$API_DATA"
}
function populate_options() {
    local key="$1"
    local current_version="$2"
    local filter="$3"
    local versions
    versions=$(fetch_versions "$filter" "$key")
    while IFS= read -r version; do
        if (( $(bc <<<"$current_version < $version") )); then
            MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE $key $version"
            ((CURRENT_INDEX++))
        fi
    done <<<"$versions"
}

# Required x86_64-v2 flags
#required_v2_flags=("cx16" "sse4_1" "sse4_2" "popcnt" "movbe" "xsave")
required_v2_flags=("cx16" "sse4_1" "sse4_2" "popcnt" "movbe" "xsave")

# Required x86_64-v3 flags
#required_v3_flags=("cx16" "sse4_1" "sse4_2" "popcnt" "movbe" "xsave" "avx" "avx2" "bmi1" "bmi2" "fma" "abm")

# CPU flags from /proc/cpuinfo
cpu_flags=$(grep -m1 "^flags" /proc/cpuinfo | awk '{for (i=2; i<=NF; i++) print $i}')

# Function to check if all required flags are present
function check_x86_64_v2_support() {
    for flag in "${required_v2_flags[@]}"; do
        if ! grep -qw "$flag" <<< "$cpu_flags"; then
            echo "CPU does not support x86_64-v2 (missing flag: $flag)"
            return 1
        fi
    done
    echo "CPU supports x86_64-v2"
    return 0
}

# Elevated permissions check unless DRYRUN is set
if [ -z "${DRYRUN:-}" ]; then
    if [ "$EUID" -ne 0 ]; then
        exec sudo "$0" "$@"
    fi

	# Requires elevated permissions or test will always fail
	test -w / || { echo "Please run the tool inside 'transactional-update shell' on Immutable systems."; exit 1; }
fi


# System-specific options
if [[ "$NAME" == "openSUSE Leap Micro" ]]; then
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="MicroOS"
    ((CURRENT_INDEX++))
    if [[ $PRERELEASE ]]; then
        populate_options "LeapMicro" "$VERSION" '.state!="EOL"'
    else
        populate_options "LeapMicro" "$VERSION" '.state=="Stable"'
    fi
elif [[ "$NAME" == "openSUSE Leap" ]]; then
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="SUSE Linux Enterprise $(sed 's/\./ SP/' <<<"$VERSION")"
    ((CURRENT_INDEX++))
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE Tumbleweed"
    ((CURRENT_INDEX++))
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE Tumbleweed-Slowroll"
    ((CURRENT_INDEX++))
    if [[ $PRERELEASE ]]; then
        populate_options "Leap" "$VERSION" '.state!="EOL"'
    else
        populate_options "Leap" "$VERSION" '.state=="Stable"'
    fi
elif [[ "$NAME" == "openSUSE Tumbleweed" ]]; then
   MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE Tumbleweed-Slowroll"
   ((CURRENT_INDEX++))
   echo
elif [[ "$NAME" == "openSUSE Tumbleweed-Slowroll" ]]; then
    MIGRATION_OPTIONS["$CURRENT_INDEX"]="openSUSE Tumbleweed"
    ((CURRENT_INDEX++))
else
    dialog --clear \
    --title "[EXPERIMENTAL] System Migration - NOT FOR PRODUCTION" \
	--msgbox "\nMigration from $NAME is currently not supported.\n\nPlease report issue at https://github.com/openSUSE/opensuse-migration-tool" \
    10 60
    reset; exit 1;
fi

# Display migration options
if [[ ${#MIGRATION_OPTIONS[@]} -eq 0 ]]; then
    dialog --clear \
    --title "[EXPERIMENTAL] System Migration - NOT FOR PRODUCTION" \
	--msgbox "\nNo migration options available from $NAME.\n\nPlease report issue at https://github.com/openSUSE/opensuse-migration-tool." \
    10 60
    reset; exit 1
    echo "."

fi
# Prepare dialog items
DIALOG_ITEMS=()
for key in "${!MIGRATION_OPTIONS[@]}"; do
    DIALOG_ITEMS+=("$key" "${MIGRATION_OPTIONS[$key]}")
done
# Display dialog and get choice
CHOICE=$(dialog --clear \
    --title "[EXPERIMENTAL] System Migration - NOT FOR PRODUCTION" \
    --menu "Select the migration target from $NAME:" \
    20 60 10 \
    "${DIALOG_ITEMS[@]}" \
    2>&1 >/dev/tty) || exit

rpmsave_repo() {
### XXX: This could go away if we install openSUSE-repos before migration
### It does the same thing
for repo_file in \
repo-backports-debug-update.repo repo-oss.repo repo-backports-update.repo \
repo-sle-debug-update.repo repo-debug-non-oss.repo repo-sle-update.repo \
repo-debug.repo repo-source.repo repo-debug-update.repo repo-update.repo \
repo-debug-update-non-oss.repo repo-update-non-oss.repo repo-non-oss.repo \
download.opensuse.org-oss.repo download.opensuse.org-non-oss.repo download.opensuse.org-tumbleweed.repo \
repo-openh264.repo openSUSE-*-0.repo repo-main.repo $TMP_REPO_NAME.repo; do
  if [ -f /etc/zypp/repos.d/$repo_file ]; then
    echo "Storing old copy as /etc/zypp/repos.d/$repo_file.rpmsave"
    $DRYRUN mv /etc/zypp/repos.d/$repo_file /etc/zypp/repos.d/$repo_file.rpmsave
  fi
done
# regexpes
for file in /etc/zypp/repos.d/openSUSE-*.repo; do
    repo_file=$(basename $file)
    if [ -f /etc/zypp/repos.d/$repo_file ]; then
        echo "Storing old copy as /etc/zypp/repos.d/$repo_file.rpmsave"
        $DRYRUN mv /etc/zypp/repos.d/$repo_file /etc/zypp/repos.d/$repo_file.rpmsave
    fi
done
# Ensure to drop any SCC generated service/repo files for Leap
# e.g. /etc/zypp/services.d/openSUSE_Leap_15.6_x86_64.service
for file in /etc/zypp/services.d/openSUSE_*.service; do
    service_file=$(basename $file)
    if [ -f /etc/zypp/services.d/$service_file ]; then
        echo "Storing old copy as /etc/zypp/repos.d/$service_file.rpmsave"
        $DRYRUN mv /etc/zypp/services.d/$service_file /etc/zypp/services.d/$service_file.rpmsave
    fi
done
}
# Clear the screen and handle the user choice
clear
if [[ -n $CHOICE ]]; then
    echo "Selected option: ${MIGRATION_OPTIONS[$CHOICE]}"
    case "${MIGRATION_OPTIONS[$CHOICE]}" in
        *"SUSE Linux Enterprise"*|"SLE")
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"

            SP=$(sed 's/\./-SP/' <<<"$VERSION") # VERSION from /etc/os-release 15.6 -> 15-SP6

            while true; do
                # Capture output and return code
                OUTPUT=$(dialog --clear \
                    --backtitle "SCC - Registration code" \
                    --title "SCC - Registration code" \
                    --form "\nPlease enter valid email and registration code." 25 60 16 \
                    "Email:" 1 1 "" 1 25 25 50 \
                    "Regcode:" 2 1 "" 2 25 25 50 \
                    2>&1 >/dev/tty)
                RETCODE=$?

                #echo "Dialog output: '$OUTPUT'" >&2
                #echo "Return code: $RETCODE" >&2

                # Handle cancel or escape
                if [[ $RETCODE -ne 0 ]]; then
                    dialog --clear \
                        --backtitle "SCC - Registration code" \
                        --title "Operation Cancelled" \
                        --msgbox "You have cancelled the registration process." 10 40
                    reset; exit 1
                fi

                {
                    read -r EMAIL
                    read -r REGCODE 
                } <<< "$OUTPUT"
            
                # Check if both values are entered
                if [[ -n "$EMAIL" && -n "$REGCODE" ]]; then
                    break
                else
                    dialog --clear \
                        --backtitle "SCC - Registration code" \
                        --title "Input Error" \
                        --msgbox "Both email and registration code are required. Please try again." 10 40
                fi
            done

            # This is a dream workflow that doesn't really work. Enable BCI repo and register as SLES with BCI-release
            # Perhaps we can fix it in near future
            #$DRYRUN zypper ar -f https://updates.suse.com/SUSE/Products/SLE-BCI/$SP/$ARCH/product/ $TMP_REPO_NAME
            #$DRYRUN zypper in --force-resolution -y suseconnect-ng
            #$DRYRUN zypper in --force-resolution -y unified-installer-release SLE_BCI-release # sles-release is not in BCI

            MAJVER=$(echo $VERSION| awk -F"." '{ print $1 }') # 15
            MINVER=$(echo $VERSION| awk -F"." '{ print $2 }') # 6
            echo $REGCODE
            $DRYRUN zypper in -y suseconnect-ng snapper grub2-snapper-plugin
            # Backup /etc/os-release before release package removal
            echo "Backing up /etc/os-release as /etc/os-release.backup"
            $DRYRUN cp /etc/os-release /etc/os-release.backup
            $DRYRUN rpm -e --nodeps openSUSE-release
            $DRYRUN rpm -e --nodeps openSUSE-repos
             # Backup the release
            echo "Backing up /etc/os-release as /etc/os-release.backup"
            $DRYRUN cp /etc/os-release /etc/os-release.backup
            if [ -z "$DRYRUN" ]; then
                cat > /etc/os-release  << EOL
NAME="SLES" 
VERSION="$SP" 
VERSION_ID="$VERSION"
PRETTY_NAME="SUSE Linux Enterprise Server $MAJVER SP$MINVER"
ID="sles"
ID_LIKE="suse"
ANSI_COLOR="0;32" 
CPE_NAME="cpe:/o:suse:sles:$MAJVER:sp$MINVER"
DOCUMENTATION_URL="https://documentation.suse.com/"
EOL
            else
                echo "Would write a SLES $SP like /etc/os-release"
            fi

			if [ -f  "$SCRIPT_DIR/SLES.prod" ]; then
				$DRYRUN cp $SCRIPT_DIR/SLES.prod /etc/products.d
			else
				$DRYRUN cp /usr/share/opensuse-migration-tool/SLES.prod /etc/products.d
			fi
	        $DRYRUN cp SLES.prod /etc/products.d/
            $DRYRUN rm -r /etc/products.d/baseproduct
            $DRYRUN ln -s /etc/products.d/SLES.prod /etc/products.d/baseproduct
            if [ -z "$DRYRUN" ]; then
                rpmsave_repo # invalidates all standard openSUSE repos
            fi

	        $DRYRUN suseconnect -e  $EMAIL -r $REGCODE 
	        $DRYRUN SUSEConnect -p PackageHub/$VERSION/$ARCH

            $DRYRUN zypper dup -y --force-resolution --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper dup --force-resolution --allow-vendor-change --download in-advance 
            fi


            $DRYRUN rpm -e --nodeps branding-openSUSE grub2-branding-openSUSE wallpaper-branding-openSUSE plymouth-branding-openSUSE systemd-presets-branding-openSUSE systemd-presets-branding-MicroOS
	        $DRYRUN zypper remove -y opensuse-welcome # might not be present on text-installations
	        $DRYRUN zypper in -y branding-SLE-15 grub2-branding-SLE wallpaper-branding-SLE-15 plymouth-branding-SLE systemd-presets-branding-SLE
            ;;
        "openSUSE Tumbleweed")
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"
            # https://download.opensuse.org/ports/ # for other arches
            REPOURL="https://download.opensuse.org/tumbleweed/repo/oss/"
            if [ "$ARCH" != "x86_64" ]; then
                REPOURL=https://download.opensuse.org/ports/$ARCH # XXX this will likely work only for aarch64
                if [ "$ARCH" != "aarch64" ]; then 
                    # Let's not messup any systems and make sure this is properly implemented first
                    echo "Unsupported arch '$ARCH'."
                    echo "Please open an issue at https://github.com/openSUSE/opensuse-migration-tool/issues"
                    echo "Make sure to add output of 'uname -i' and content of your /etc/os-release into the ticket."
                    exit 1
                fi
            fi
            $DRYRUN zypper addrepo -f $REPOURL $TMP_REPO_NAME
            $DRYRUN zypper in -y --from $TMP_REPO_NAME openSUSE-repos-Leap # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refs # !Important! make sure that all repo files under index service were regenerated
            
            $DRYRUN zypper dup -y --force-resolution --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper dup --force-resolution --allow-vendor-change --download in-advance 
            fi

            ;;
        "openSUSE Tumbleweed-Slowroll")
            $DRYRUN echo "Migrating to ${MIGRATION_OPTIONS[$CHOICE]}"
            REPOURL="https://download.opensuse.org/slowroll/repo/oss/"
            if [ "$ARCH" != "x86_64" ]; then
                echo "Unsupported arch '$ARCH' by Slowroll."
                exit 1
            fi
            $DRYRUN zypper addrepo -f $REPOURL $TMP_REPO_NAME
            $DRYRUN zypper in -y --from $TMP_REPO_NAME openSUSE-repos-Slowroll # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refs # !Important! make sure that all repo files under index service were regenerated
            
            $DRYRUN zypper dup -y --force-resolution --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper dup --force-resolution --allow-vendor-change --download in-advance 
            fi
            ;;
        *"openSUSE LeapMicro"*)
            # Has to be before Leap*
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"
            TARGET_VER=`echo ${MIGRATION_OPTIONS[$CHOICE]} | awk '{ print $NF }'`
            $DRYRUN zypper addrepo -f https://download.opensuse.org/distribution/leap-micro/$TARGET_VER/product/repo/openSUSE-Leap-Micro-$TARGET_VER-$ARCH/ $TMP_REPO_NAME
            $DRYRUN zypper in -y --from $TMP_REPO_NAME openSUSE-repos-LeapMicro # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refs # !Important! make sure that all repo files under index service were regenerated

            $DRYRUN zypper --releasever $TARGET_VER dup -y --force-resolution --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper --releasever $TARGET_VER dup --force-resolution --allow-vendor-change --download in-advance 
            fi
            ;;
        *"openSUSE Leap"*)
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"
            TARGET_VER=`echo ${MIGRATION_OPTIONS[$CHOICE]} | awk '{ print $NF }'`
            if [ "$ARCH" == "x86_64" ] && [[ ${TARGET_VER%.*} -ge 16 ]] && ! check_x86_64_v2_support; then
                #echo "Unsupported CPU for openSUSE Leap $TARGET_VER"
                dialog --clear \
                    --title "System Migration - Unsupported architecture" \
	--msgbox "\n${MIGRATION_OPTIONS[$CHOICE]} does not support your CPU architecture. The minimum baseline is x86_64-v2.\n\nSee https://en.opensuse.org/openSUSE:X86-64-Architecture-Levels" \
    10 60
    reset; exit 1
            fi
                
            $DRYRUN zypper addrepo -f https://download.opensuse.org/distribution/leap/$TARGET_VER/repo/oss $TMP_REPO_NAME
            $DRYRUN zypper in -y --from $TMP_REPO_NAME openSUSE-repos-Leap # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refs # !Important! make sure that all repo files under index service were regenerated

            $DRYRUN zypper --releasever $TARGET_VER dup -y --force-resolution --allow-vendor-change --download-in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper --releasever $TARGET_VER dup --force-resolution --allow-vendor-change --download-in-advance
            fi
            ;;
        *"MicroOS"*)
            $DRYRUN echo "Upgrading to ${MIGRATION_OPTIONS[$CHOICE]}"
            # https://download.opensuse.org/ports/ # for other arches
            REPOURL="https://download.opensuse.org/tumbleweed/repo/oss/"
            if [ "$ARCH" != "x86_64" ]; then
                REPOURL=https://download.opensuse.org/ports/$ARCH # XXX this will likely work only for aarch64
                if [ "$ARCH" != "aarch64" ]; then 
                    # Let's not messup any systems and make sure this is properly implemented first
                    echo "Unsupported arch '$ARCH'."
                    echo "Please open an issue at https://github.com/openSUSE/opensuse-migration-tool/issues"
                    echo "Make sure to add output of 'uname -i' and content of your /etc/os-release into the ticket."
                    exit 1
                fi
            fi
            $DRYRUN zypper addrepo -f $REPOURL $TMP_REPO_NAME
			$DRYRUN zypper in -y --from $TMP_REPO_NAME openSUSE-repos-MicroOS # install repos from the nextrelease
            $DRYRUN zypper removerepo $TMP_REPO_NAME # drop the temp repo, we have now definitions of all repos we need
            $DRYRUN zypper refs # !Important! make sure that all repo files under index service were regenerated
            
            $DRYRUN zypper dup -y --force-resolution --allow-vendor-change --download in-advance
            if [ $? -ne 0 ]; then # re-run zypper dup as interactive in case of failure in non-interactive mode
                $DRYRUN zypper dup --force-resolution --allow-vendor-change --download in-advance 
            fi
            ;;
    esac
else
    echo "No option selected. Exiting."
    exit 1
fi

#dialog --clear \
#    --backtitle "[EXPERIMENTAL] Migration tool" \
#    --title "Migration process completed" \
#    --msgbox "\nMigration process completed.\nA reboot is recommended." 10 40
#
echo "Migration process completed. A reboot is recommended."
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000B00000000TRAILER!!!83 blocks
openSUSE Build Service is sponsored by