github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/stage1/gc/gc.go (about)

     1  // Copyright 2015 The rkt Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  //+build linux
    16  
    17  package main
    18  
    19  import (
    20  	"flag"
    21  	"fmt"
    22  	"io/ioutil"
    23  	"log"
    24  	"os"
    25  	"path/filepath"
    26  	"runtime"
    27  
    28  	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema/types"
    29  
    30  	"github.com/coreos/rkt/common"
    31  	"github.com/coreos/rkt/networking"
    32  )
    33  
    34  var (
    35  	debug bool
    36  )
    37  
    38  func init() {
    39  	flag.BoolVar(&debug, "debug", false, "Run in debug mode")
    40  
    41  	// this ensures that main runs only on main thread (thread group leader).
    42  	// since namespace ops (unshare, setns) are done for a single thread, we
    43  	// must ensure that the goroutine does not jump from OS thread to thread
    44  	runtime.LockOSThread()
    45  }
    46  
    47  func main() {
    48  	flag.Parse()
    49  
    50  	if !debug {
    51  		log.SetOutput(ioutil.Discard)
    52  	}
    53  
    54  	podID, err := types.NewUUID(flag.Arg(0))
    55  	if err != nil {
    56  		fmt.Fprintln(os.Stderr, "UUID is missing or malformed")
    57  		os.Exit(1)
    58  	}
    59  
    60  	if err := gcNetworking(podID); err != nil {
    61  		fmt.Fprintln(os.Stderr, err)
    62  		os.Exit(1)
    63  	}
    64  }
    65  
    66  func gcNetworking(podID *types.UUID) error {
    67  	var flavor string
    68  	// we first try to read the flavor from stage1 for backwards compatibility
    69  	flavor, err := os.Readlink(filepath.Join(common.Stage1RootfsPath("."), "flavor"))
    70  	if err != nil {
    71  		// if we couldn't read the flavor from stage1 it could mean the overlay
    72  		// filesystem is already unmounted (e.g. the system has been rebooted).
    73  		// In that case we try to read it from the pod's root directory
    74  		flavor, err = os.Readlink("flavor")
    75  		if err != nil {
    76  			return fmt.Errorf("Failed to get stage1 flavor: %v\n", err)
    77  		}
    78  	}
    79  
    80  	n, err := networking.Load(".", podID)
    81  	switch {
    82  	case err == nil:
    83  		n.Teardown(flavor)
    84  	case os.IsNotExist(err):
    85  		// probably ran with --net=host
    86  	default:
    87  		return fmt.Errorf("Failed loading networking state: %v", err)
    88  	}
    89  
    90  	return nil
    91  }