@@ -191,6 +191,7 @@ type ServerInstallPath = {
191191 Icon : ComponentType < { className ?: string } > ;
192192 commandTitle : string ;
193193 command : string [ ] ;
194+ commands ?: InstallCommand [ ] ;
194195 chips : string [ ] ;
195196 actions ?: {
196197 href : string ;
@@ -199,6 +200,54 @@ type ServerInstallPath = {
199200 } [ ] ;
200201} ;
201202
203+ type InstallCommand = {
204+ id : string ;
205+ label : string ;
206+ title : string ;
207+ command : string [ ] ;
208+ } ;
209+
210+ function InstallCommandTabs ( {
211+ commands,
212+ } : {
213+ commands : InstallCommand [ ] ;
214+ } ) {
215+ const [ activeCommandId , setActiveCommandId ] = useState ( commands [ 0 ] . id ) ;
216+ const activeCommand =
217+ commands . find ( ( command ) => command . id === activeCommandId ) ?? commands [ 0 ] ;
218+
219+ return (
220+ < div >
221+ < div className = "mb-3 flex border-b border-border" role = "tablist" aria-label = "Linux install methods" >
222+ { commands . map ( ( command ) => {
223+ const isActive = command . id === activeCommand . id ;
224+
225+ return (
226+ < button
227+ key = { command . id }
228+ type = "button"
229+ role = "tab"
230+ aria-selected = { isActive }
231+ onClick = { ( ) => setActiveCommandId ( command . id ) }
232+ className = { cn (
233+ "border-b-2 border-b-transparent px-4 py-2 text-sm font-semibold text-muted-foreground transition-colors hover:text-foreground" ,
234+ isActive && "border-b-brand text-brand"
235+ ) }
236+ >
237+ { command . label }
238+ </ button >
239+ ) ;
240+ } ) }
241+ </ div >
242+ < CodeBlock
243+ title = { activeCommand . title }
244+ code = { activeCommand . command }
245+ className = "border-brand/60 shadow-[0_0_0_1px_rgba(39,112,246,0.18),0_18px_60px_rgba(39,112,246,0.12)]"
246+ />
247+ </ div >
248+ ) ;
249+ }
250+
202251function KubernetesInstallCommands ( ) {
203252 const methods = [
204253 {
@@ -262,6 +311,18 @@ function ServerInstallTabs({ release }: { release: GitHubRelease | null }) {
262311 const x86Gnu = findReleaseAsset ( release , [ / r u s t f s - l i n u x - x 8 6 _ 6 4 - g n u .* \. z i p / i] , 'rustfs-linux-x86_64-gnu-latest.zip' ) ;
263312 const armMusl = findReleaseAsset ( release , [ / r u s t f s - l i n u x - a a r c h 6 4 - m u s l .* \. z i p / i] , 'rustfs-linux-aarch64-musl-latest.zip' ) ;
264313 const armGnu = findReleaseAsset ( release , [ / r u s t f s - l i n u x - a a r c h 6 4 - g n u .* \. z i p / i] , 'rustfs-linux-aarch64-gnu-latest.zip' ) ;
314+
315+ // DEB/RPM native packages from R2
316+ const R2_PKG_BASE = 'https://dl.rustfs.com/artifacts/rustfs/packages/release' ;
317+ const tagName = release ?. tag_name ?? '' ;
318+ const debVersion = tagName . replace ( '-' , '~' ) ; // 1.0.0-rc.1 -> 1.0.0~rc.1
319+ const rpmVersion = tagName . replace ( '-' , '_' ) ; // 1.0.0-rc.1 -> 1.0.0_rc.1
320+ const debAmd64Url = tagName ? `${ R2_PKG_BASE } /rustfs_${ debVersion } _amd64.deb` : '' ;
321+ const debArm64Url = tagName ? `${ R2_PKG_BASE } /rustfs_${ debVersion } _arm64.deb` : '' ;
322+ const rpmX86Url = tagName ? `${ R2_PKG_BASE } /rustfs-${ rpmVersion } -1.x86_64.rpm` : '' ;
323+ const rpmArm64Url = tagName ? `${ R2_PKG_BASE } /rustfs-${ rpmVersion } -1.aarch64.rpm` : '' ;
324+ const debAmd64Filename = debAmd64Url . split ( '/' ) . pop ( ) ?? '' ;
325+ const rpmX86Filename = rpmX86Url . split ( '/' ) . pop ( ) ?? '' ;
265326 const macArmUrl = release
266327 ? getDownloadUrlForPlatform ( release , 'macos' , 'aarch64' )
267328 : null ;
@@ -284,12 +345,54 @@ function ServerInstallTabs({ release }: { release: GitHubRelease | null }) {
284345 command : [
285346 'curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh' ,
286347 ] ,
287- chips : [ 'MUSL / GNU' , 'x86_64 / ARM64' , 'system service' ] ,
348+ commands : [
349+ {
350+ id : 'script' ,
351+ label : 'Script' ,
352+ title : 'Fast validation' ,
353+ command : [
354+ 'curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh' ,
355+ ] ,
356+ } ,
357+ ...( debAmd64Url
358+ ? [
359+ {
360+ id : 'deb' ,
361+ label : 'DEB' ,
362+ title : 'Debian / Ubuntu package' ,
363+ command : [
364+ `curl -O ${ debAmd64Url } ` ,
365+ `sudo dpkg -i ${ debAmd64Filename } ` ,
366+ 'rustfs --version' ,
367+ ] ,
368+ } ,
369+ ]
370+ : [ ] ) ,
371+ ...( rpmX86Url
372+ ? [
373+ {
374+ id : 'rpm' ,
375+ label : 'RPM' ,
376+ title : 'RHEL / Fedora package' ,
377+ command : [
378+ `curl -O ${ rpmX86Url } ` ,
379+ `sudo rpm -ivh ${ rpmX86Filename } ` ,
380+ 'rustfs --version' ,
381+ ] ,
382+ } ,
383+ ]
384+ : [ ] ) ,
385+ ] ,
386+ chips : [ 'MUSL / GNU' , 'DEB / RPM' , 'x86_64 / ARM64' , 'system service' ] ,
288387 actions : [
289388 { href : x86Musl . url , label : 'x86_64 MUSL' , icon : < LinuxIcon className = "size-4" /> } ,
290389 { href : x86Gnu . url , label : 'x86_64 GNU' , icon : < LinuxIcon className = "size-4" /> } ,
291390 { href : armMusl . url , label : 'ARM64 MUSL' , icon : < LinuxIcon className = "size-4" /> } ,
292391 { href : armGnu . url , label : 'ARM64 GNU' , icon : < LinuxIcon className = "size-4" /> } ,
392+ ...( debAmd64Url ? [ { href : debAmd64Url , label : 'DEB amd64' , icon : < LinuxIcon className = "size-4" /> } ] : [ ] ) ,
393+ ...( debArm64Url ? [ { href : debArm64Url , label : 'DEB arm64' , icon : < LinuxIcon className = "size-4" /> } ] : [ ] ) ,
394+ ...( rpmX86Url ? [ { href : rpmX86Url , label : 'RPM x86_64' , icon : < LinuxIcon className = "size-4" /> } ] : [ ] ) ,
395+ ...( rpmArm64Url ? [ { href : rpmArm64Url , label : 'RPM aarch64' , icon : < LinuxIcon className = "size-4" /> } ] : [ ] ) ,
293396 ] ,
294397 } ,
295398 {
@@ -444,7 +547,9 @@ function ServerInstallTabs({ release }: { release: GitHubRelease | null }) {
444547 </ div >
445548
446549 < div className = "grid gap-5 p-5 sm:p-6" >
447- { activePath . id === 'kubernetes' ? (
550+ { activePath . commands ? (
551+ < InstallCommandTabs commands = { activePath . commands } />
552+ ) : activePath . id === 'kubernetes' ? (
448553 < KubernetesInstallCommands />
449554 ) : (
450555 < CodeBlock
@@ -542,7 +647,7 @@ export default function DownloadPageClient() {
542647 eyebrow = "Data service"
543648 title = "RustFS Server"
544649 description = "Server binary, Docker image, and source archive."
545- methods = { [ 'Linux' , 'Docker' , 'Compose' , 'Kubernetes' , 'macOS' , 'Windows' ] }
650+ methods = { [ 'Linux' , 'DEB / RPM' , ' Docker', 'Compose' , 'Kubernetes' , 'macOS' , 'Windows' ] }
546651 Icon = { ServerIcon }
547652 />
548653 < ProductDownloadLink
0 commit comments